IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[DOM] Onload et IFRAME : tu veux ou tu veux pas ?


Sujet :

JavaScript

  1. #1
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut [DOM] Onload et IFRAME : tu veux ou tu veux pas ?
    -- EDIT Le même jour, 15h15
    Aprés des testes supplémentaires, il apparaît que le problème n'est pas tout à fait correctement exposé dans ce premier post. Le problème existe bien, mais pas tout à fait dans ces termes. Voyez le post N°3. Dans ce post, il est dit que le problème ne se pose pas si le IFRAME est chargé avec un FORM.submit où target désigne IFRAME. En fait, cela ne fonctionne pas non-plus dans ce cas là.
    -- FIN DU EDIT

    Bonjour,

    Onload et IFRAME, c'est « tu veux ou tu veux pas ? »

    Si tu veux, c'est bien, si tu veux pas, ça m'emmerde

    Mort de rire, mais le problème est bien réel lui. J'ai constaté ce phénomène ennuyeux sur IE6...

    Soit un IFRAME, et un document qui se charge dans l'IFRAME. La proprioété onload de l'IFRAME s'est au préalable vu assigner une fonction. Voici comment les choses se déroule. Si l'IFRAME est chargé par un window.open indiquant comme cible l'IFRAME, alors l'événement onload n'est pas déclenché. Si l'IFRAME est chargé par un FORM.submit indiquant comme cible de chargement, l'IFRAME en question, alors l'événement onload sera déclenché. Si la page chargé dans l'IFRAME spécifie un attribut onload pour l'élément BODY ou un window.onload dans un fichier JavaScript attaché, alors l'événement est déclenché.

    Il existe donc un cas problématique, qui est celui ou on associe un handler onload depuis l'extérieure de la page elle-même et que la page est chargé avec window.open.

    Quelques exemple de code abrégé rendront ce charabiat plus parlant.

    Code inclus dans page-1.html
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    <IFRAME name="monIframe"></IFRAME>
    Code inclus dans un fichier .js attaché à page-1.html
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    var monIframe = window.frames("monIframe");
     
    monIframe.onload = test;
     
    function test ()
    {
       alert("Le document est arrivé (cheese)");
    }
     
    window.open("page-2.html", "monIframe");
    On pourrait s'attendre à ce que la procédure « test » se déclenche, ... hé bien non! Il n'en est rien justement.

    Mais si on fait
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    <FORM ... name="maForm" action="page-2.html" target="monIframe"></FORM>
    et que l'on fait ensuite
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    maForm.submit();
    Là, la procédure « test » est exécutée.

    Reprenons le premier cas, celui d'un chargement par window.open. Si on place dans page-2.html
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    <BODY onLoad="test2();">...</BODY>
    et que l'on place dans un fichier JavaScript attaché à page-2.html
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function test2 ()
    {
       alert("Le document est arrivé (bis)");
    }
    Là, même si on ouvre avec window.open, la procédure test2 sera exécuté.

    Donc, quand on assigne onload à l'IFRAME depuis un script attaché à la page qui contient l'IFRAME et qu'on le charge avec window.open, le onload défini par le script attaché à la page d'appel ne sera pas déclenché.

    Alors pourquoi ? Est-ce un bug ? Je l'ignore, en tous cas, je le constate ....

    Bonne journée

    P.S. Excusez si ça fait un peu tartine-confuse, mais je ne parviens pas à formuler le cas autrement

  2. #2
    Membre émérite
    Inscrit en
    Septembre 2002
    Messages
    2 307
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 2 307
    Points : 2 814
    Points
    2 814
    Par défaut
    problème de synchro
    monIframe.onload = test;
    si le code est avant le chargement, la page chargé détruit le onload avec le sien (même null).
    si le code est après le chargement, la page est déjà chargé donc le onload ne sert à rien...

  3. #3
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    Alut
    Citation Envoyé par Matthieu2000
    si le code est avant le chargement, la page chargé détruit le onload avec le sien (même null).
    si le code est après le chargement, la page est déjà chargé donc le onload ne sert à rien...
    Le onload est fixé, puis le IFRAME est chargé plusieurs fois. Et si c'était le chargement de la page qui détruit le onload, alors pourquoi cela fonctionne t-il quand on donne sa valeur à l'attribut onload dans le code de la balise IFRAME (dans le code source HTML) ? Parce qu'alors dans ce cas, pourquoi cet attribut là ne serait pas détruit ? Il serait détruit s'il a été fixé par le script, mais pas s'il a été fixé dans le code HTML de la balise IFRAME ?

    En fait, j'ai mal formulé le problème dans le premier post, et ça ne fonctionne pas non-plus avec le FORM.submit. J'ai cru que ça fonctionnait, parce que l'attribut onload pour le IFRAME de destination de ce cas, était donné dans le code HTML de la page, en plus d'être fixé par le fichier JavaScript.

    Si je retire l'attribut dans le code source HTML, ça ne fonctionne plus.

    Le problème, aprés analyse plus compléte, se présente comme suit :

    Si on a
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    <IFRAME name="myIframe">...
    et
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    window.frames("myIframe").onload = test;
    la routine « test » ne sera jamais appelée.

    Mais si on a
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    <IFRAME name="myIframe" onload="test();">...
    alors ça marche.

    Ceci est vrai quelque soit la manière dont le IFRAME est chargé, aussi bien par window.open que par FORM.submit (où FORM.target = "myIframe").

    En d'autres terme, l'attribut onload ne peut pas être modifier depuis JavaScript, sauf à l'exception notable bien sûre du fameux "window.onload = ...", qui fonctionne, mais seulement dans ce cas, et pas pour une être fenêtre. Apparement, ne script ne peut modifier réellement l'attribut onload que de la fenêtre à laquelle le script est attaché. Sinon, il faut donner l'attribut onload dans le code HTML.

    Bizarre quand-même tout ça... :-/

  4. #4
    Membre expert
    Avatar de FremyCompany
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 2 532
    Points : 3 239
    Points
    3 239
    Par défaut
    Euh... dois y avoir confusion...

    window.frames["frameName"] ne renvoie pas le tag IFRAME mais l'objet Window contenu dans l'IFRAME...

    Explication :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    frames["frameName"]=document.getElementsByName("frameName")[0].window
    Les deux ne parlent donc pas du même onload

  5. #5
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    Salut,
    Citation Envoyé par FremyCompany
    Euh... dois y avoir confusion...
    window.frames["frameName"] ne renvoie pas le tag IFRAME mais l'objet Window contenu dans l'IFRAME...
    [/CODE]
    Où ais-je dis que ça renvoyait un tag ? D'ailleurs aucune fonction DOM ne renvoit de tag... elles renvoient des objets associés à des éléments (entre autre).

    Dans un cas, l'attribut onload est fixé dans le code HTML, par un attribut dans le balise IFRAME.
    Dans l'autre cas, l'attribut onload est fixé par une instruction JavaScript, c'est à dire par une propriété de l'objet IFRAME.

    Dans le premier cas, onload est fonctionel, dans le deuxième cas, il ne l'est pas.... d'où le problème (et la bizarrerie)

    Note: donner l'attribut onload à l'élément ou à la fenêtre, produit exactement le même effet. C'est exactement comme donné l'attribut onload à l'élément BODY dans le code HTML, ou la fenêtre comme dans window.onload = ... Ca ne fait aucune différence (c'est peut-être de ça que tu voulais parler). De toute façon, je ne pourrais pas donner l'attribut onload à un BODY du contenu d'un élément encore non-chargé. Ceci n'a de sens que dans un code HTML, et dans un code JavaScript, c'est à un objet fenêtre qu'on applique l'attribut onload (du moins pour ce que j'en sais).

    Sinon, c'est vrai qu'il est important dans d'autres circonstance, de faire la distinction entre « l'aspect fenêtre » et « l'aspect élément » (même si on m'a fait remarquer que le mot « aspect » ou « facette » n'est pas courant dans le monde JavaScript).

    Oilà

  6. #6
    Membre expert
    Avatar de FremyCompany
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 2 532
    Points : 3 239
    Points
    3 239
    Par défaut
    Je suis pas sur que tu aies compris ce que je voulais dire.

    frames["frameName"] renvoie en fait document.getElementsByName("frameName")[0].window;

    Si tu veux mettre un onload à ton IFRAME, tu dois faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    document.getElementsByName("frameName")[0].onload = function() {}
    et pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    frames["framName"].onload = function() {}
    C'est deux objets tout à fait différents
    La première fois (frames["x"]), tu recoit un HTMLWindow, la deuxième (getElementsByName) tu recoit un HTMLIFrameElement

    Quand tu mets un onload via un attribut HTML, tu change le onload de l'iframe donc de l'instance de HTMLIFrameElement, pas de HTMLWindow

    Teste par toi-même, remplace ton frames["x"] par getElementsByName et tu verras si ce que je penses ce confirme ou pas

  7. #7
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    Ah, c'est interessant tout ça. Dans quelle référence as-tu put apprendre tout ça ? Je vais essayer plus tard.

    Sinon, par curiosité... quel est alors l'objet
    document.getElementsByName("frameName")[0] ?
    Pourquoi n'est-ce pas
    document.getElementsByName("frameName").window
    au lieu de
    document.getElementsByName("frameName")[0].window ?

  8. #8
    Membre expert
    Avatar de FremyCompany
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 2 532
    Points : 3 239
    Points
    3 239
    Par défaut
    getElementsByName retourne un Array
    En effet, plusieurs objets dans ta page peuvent avoir le même nom...

    Pour bien faire, tu devrais parcourrir l'Array jusqu'à trouver ton IFRAME...

  9. #9
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    Citation Envoyé par FremyCompany
    [...] La première fois (frames["x"]), tu recoit un HTMLWindow, la deuxième (getElementsByName) tu recoit un HTMLIFrameElement [...]
    Mais pour ça, c'est ça qui m'éveillait des questions. JavaScript n'étant pas typé au sens stricte (il n'y a que des objet, pas de vrai classe), c'est sûrement informel. Et dans les docs, je ne trouve rien qui parle de HTMLWindow et HTMLIframe. Ca ne parle que de IFRAME (qui est un élément), et qui peut avoir un window, quand le IFRAME a un contenu.

    C'est pour cela que je ne comprenais pas pourquoi getElementsByName et frames[...] ne renvoit pas la même chose.

    Au passage, je n'ai encore pas fait ce teste... il faut que j'y pense.

  10. #10
    Membre expert
    Avatar de FremyCompany
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 2 532
    Points : 3 239
    Points
    3 239
    Par défaut
    JavaScript n'a pas de typage, mais tu te doutes bien qu'Internet Explorer n'est pas fait en JavaScript

    Les objets que tu utilises sont des "représentations" d'objet C++
    En gros, c'est une passerelle de communication entre JavaScript et le navigateur.

    Et puis je ne vois pas en quoi le fait de frames["x"] renvoie la fenêtre contenue dans l'iframe et pas l'objet IFRAME lui-même est un problème

    C'est ce que le W3C a demandé, c'est ce que les navigateurs ont fait (à moins que ce ne soit le contraire )

  11. #11
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    Citation Envoyé par FremyCompany
    Et puis je ne vois pas en quoi le fait de frames["x"] renvoie la fenêtre contenue dans l'iframe et pas l'objet IFRAME lui-même est un problème
    Ouiiii! mais justement. On écrit toujours window.onload = init ... pour initialiser une application JavaScript. Quoique quand on le donne dans le code HTML, on l'attache à BODY. Donc le fait de faire window.onload = init serait donc en fait une entorse ou un raccourci particulier, et en réalité, on doit donc attacher l'événement à l'élément et non-pas à le fenêtre. C'est vrai que ça semble plus logique dans le fond, puisque les autres événement sont aprés-tout toujours attachés à des éléments (onclick, onfocus, etc). Alors on ne devrait pas faire window.init = ... mais plutôt document.getElementsByTagName('BODY')[0].onload = .... C'est ça ? Pfff... si je continue, je vais avoir l'air vraiment idiot, alors je vais peut-être m'arrêter là.

    Mais alors quand-même, c'est idiot d'avoir autorisé des raccourcis comme window.onload = ... ça cré la confusion.

    -- EDIT le même jour, 20h08
    Non, attacher l'événement à l'élément BODY ne fonctionne pas depuis un script. Mais l'attaché à l'objet retourner par document.getElementsByName ou getElementById (ou autre), fonctionne (pour un IFRAME). Les IFRAME ne sont donc pas des fenêtre comme les autres. Les fenêtre ordinnaire et les popups, sont un type de fenêtre, et les IFRAME sont un autre type de fenêtre. Si JavaScript était typé, on pourrait que ce n'est pas la même classe. Question : est-il possible de récupérer ce qui correspond à l'élément d'un IFRAME à partire d'un objet qui correspond à sa fenêtre ? Je viens de vérifier : c'est impossible. On ne peut pas récupérer l'élément à partir de la fenêtre et on ne peut pas récupérer la fenêtre à partir de l'élément. Par commoditer, j'utilise cela :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    function getIFrameWindowWithElement (name)
    {
       var element;
       var window;
       element = document.getElementsByName(name)[0];
       window = document.frames(name);
       window.element = element;
       return window;
    }
    // exemple d'utilisation
    var f;
    f = getIFrameWindowWithElement('name');
    f.element.onload = ...
    // et par exemple encore
    f.close ();
    // On a les deux en un seul objet, ce qui est bien commode

    -- FIN DU EDIT

    Citation Envoyé par FremyCompany
    C'est ce que le W3C a demandé, c'est ce que les navigateurs ont fait (à moins que ce ne soit le contraire )
    Je rie aussi... quelles histoires que celles-ci alors

  12. #12
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    Je n'y comprends rien, ça marche pour tout les événement, sauf onload. Et les autres événement peuvent être attaché aussi bien à l'objet fenêtre qu'à l'objet élément d'ailleur.

    J'en ai marre, je laisse tomber

    Il n'y a pas un tag « irrésoluble » sur ce forum ?

  13. #13
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    Finalement, je marque « résolu » quand-même, dans le sens où je pense avoir la certitude qu'il y a un problème spécifique avec l'événement onload (même s'il n'y a pas de solution, je sais que c'est comme ça)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 15/03/2014, 09h39
  2. [HTML 5] Iframe/vidéo qui ne se redimensionne pas
    Par Yepazix dans le forum Balisage (X)HTML et validation W3C
    Réponses: 13
    Dernier message: 28/01/2014, 23h02
  3. [DOM] Onload et Safari
    Par LapinOuf dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 18/12/2008, 10h51
  4. [DOM] form target="iframe générée" et IE
    Par martinv dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 22/10/2008, 12h19
  5. image dans une iframe div qui ne s'efface pas
    Par Invité(e) dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 26/10/2005, 11h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo