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

Contribuez Discussion :

[DOM] Ajout d'éléments à un élément parent. [JavaScript]


Sujet :

Contribuez

  1. #1
    Membre confirmé Avatar de yjuliet
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Août 2006
    Messages
    362
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 362
    Points : 460
    Points
    460
    Par défaut [DOM] Ajout d'éléments à un élément parent.
    Suite à une galère de quelques jours, je voulais juste partager une petite expérience sur un bug étrange d'Internet Explorer...

    Lorsque vous voulez ajouter un noeud à élément de votre page (un noeud DOM), si le script qui gère cet ajout n'est pas un fils direct ou en dehors du noeud dans lequel on veut ajouter l'élément, lors de l'ajout (parent.appendChild(newElement)), Internet explorer va afficher une page d'erreur au lieu du contenu de la page réellement générée, indiquant que le serveur est introuvable à cause d'un problème DNS.

    J'ai testé sous IE 6 et 7 sous XP SP2 et tous les 2 étaient impactés. J'ai aussi testé d'autres navigateurs pour voir si ils étaient impactés et le résultat a été clair aucun problème pour Firefox 2 ni Safari 3 (pour Windows).
    N'ayant pas d'autres navigateurs sous la main, je me suis contenté de ceux-ci.

    Voici donc un exemple de code pour vérifier sur votre version d'Internet Explorer :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <html>
    <body>
    <div id="myId">
      <div>
        <script type="text/javascript"><!--
    document.getElementById("myId").appendChild(document.createElement("div"));
        // --></script>
      </div>
    </div>
    </body>
    </html>
    La seule parade que j'ai trouvée était de déplacer les scripts en fonction des besoins le plus proche possible de la racine XML.

  2. #2
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 665
    Points
    66 665
    Billets dans le blog
    1
    Par défaut
    Ce qui est d'autatn plus curieux c'est que c'est non seulement l'appendChild qui pose problème mais en plus la position du nouvel élément ???
    Code : 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
    18
     
     
    <html>
    <body>
    <div id="myId">
      <div id="child" style='border: solid 3px green; height:20px;'>
        <script type="text/javascript"><!--
        var newElt=document.createElement("div")
        newElt.style.border="solid 3px red"
        newElt.style.height="20px"
        newElt.id='new'
        var container=document.getElementById("myId")
        container.insertBefore(newElt,document.getElementById('child'));
        //contianer.insertBefore(document.getElementById('child'),document.getElementById('new') )   // --></script>
      </div>
    </div>
    </body>
    </html>
    Le insertBefore ne pose pas de problème...
    mais si l'on essaye d'inverser l'ordre il se passer le même bug ???

  3. #3
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 665
    Points
    66 665
    Billets dans le blog
    1
    Par défaut
    La lumière nous vient de Auteur !

    Il m'a fait remarqué que en fait au moment de l'execution du script les balises de fermeture des div ne sont pas encore interprétées ...

    voici donc comment résoudre ce petit problème :

    Code : 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
    18
    19
    <html>
    <body>
    <div id="myId">
      <div id="child" style='border: solid 3px green; height:20px;'>
        <script type="text/javascript"><!--
        var newElt=document.createElement("div")
        newElt.style.border="solid 3px red"
        newElt.style.height="20px"
        newElt.id='new'
        var container=document.getElementById("myId")
        setTimeout(function(){container.appendChild(newElt)})
          // -->
     
         </script>
      </div>
    </div>
     
    </body>
    </html>
    et du coup les balises des divs sont fermées ...

  4. #4
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 143
    Points
    11 143
    Par défaut
    Spaceforg : bah, c'est la seule explication que j'ai trouvée... Dans l'exemple de yjuliet le code s'execute avant la fermeture du div parent... Comme le parent n'est pas fermé, on ne peut pas ajouter d'élément à la fin.

    Par contre, tu as oublié de préciser le second paramètre dans le setTimeout (la temporisation). C'est normal ?



    et pour l'insertBefore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <div id="myId">
      <div id="child" style='border: solid 3px green; height:20px;'>
        <script type="text/javascript"><!--
        var newElt=document.createElement("div")
        newElt.style.border="solid 3px red"
        newElt.style.height="20px"
        newElt.id='new'
        var container=document.getElementById("myId")
        container.insertBefore(newElt,document.getElementById('child'));
        //container.insertBefore(document.getElementById('child'),document.getElementById('new') )   // --></script>
      </div>
    </div>
    tu peux insérer avant le child car au moment de l'exécution du script la balise
    ouvrante <div id="child"> existe (même si les balises </div> des div du child et du conteneur ne sont pas encore interprétées).

    J'en suis arrivé à cette explication car lorsque l'on sort le script du conteneur :
    Code html : 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    <html>
    <head>
    <title></title>
    </head>
     
    <body>
     
      <div id="myId">
      conteneur
        <div>mon texte
     
        </div>
      </div>
     
        <script type="text/javascript"><!--
        var el = document.createElement("div");
        var c = document.getElementById("myId");
        el.innerHTML = "coucou";
        el.style.border="solid 3px red";
        c.appendChild(el);
        // -->
        </script>
     
     
    </body>
    </html>
    Cela ne pose aucun problème.

  5. #5
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 665
    Points
    66 665
    Billets dans le blog
    1
    Par défaut
    peut on simplement dire en conclusion qu'il s'agit d'un problème d'instanciation d'objet ?

    pour le paramètre manquant... non c'est eun erreur ... mais ça à l'aire de focntionner quand même ... ce qui voudrait dire que c'est une question de milliseconde ?

  6. #6
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 143
    Points
    11 143
    Par défaut
    Citation Envoyé par SpaceFrog
    peut on simplement dire en conclusion qu'il s'agit d'un problème d'instanciation d'objet ?
    sans doute... Ceci dit je ne considère pas le comportement de IE comme un bug en tant que tel.

    pour le paramètre manquant... non c'est eun erreur ... mais ça à l'aire de focntionner quand même ... ce qui voudrait dire que c'est une question de milliseconde ?
    euh là... je ne serai pas aussi catégorique : dans ces exemples, il ya "juste" trois lignes de code dans le div. Mais si après le script tu insères des éléments qui sont longs à charger (include PHP, requête Ajax, images,...), je ne suis pas sûr que le div (c'est à dire un élément <div>....</div>) soit créé en quelques millisecondes.

  7. #7
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Citation Envoyé par yjuliet
    ou en dehors du noeud dans lequel on veut ajouter l'élément, lors de l'ajout (parent.appendChild(newElement)), Internet explorer va afficher une page d'erreur ....
    Du coup, j'ai une question (certainement bête) :
    quel est l'intérêt d'un script "dans la page", par rapport à un lancement via le traditionnel onload ?
    Il sera bien en dehors du noeud en question, et du coup, ça enlève tout interrogation sur le timeout à prévoir (qui me semble de toutes façons bien aléatoire, pour les raisons données par Auteur ... auquelles je rajoute mon cas perso : les petits veinard qui ont la joie de voir les pages se contruire sous leurs yeux gràce à un modem 56K, et pour lesquels il faut rajouter 2 zéro au timeout prévu).

    ... enfin, je demande ça surtout parce que j'aime pas mettre des scripts dans le body

  8. #8
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 665
    Points
    66 665
    Billets dans le blog
    1
    Par défaut
    en fait la seule justification que je verrasi à cela serait pour ajouter des scripts javascript avec des includes en php ?

  9. #9
    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
    Regardez comment faire ce que vous voulez sans timeout, sans onload, sans trucs sans broc et sans machin non plus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <div id="divResult">Voici le résultat du script :<br/></div>
    <script>
    document.getElementById("divResult").appendChild(
      document.createTextNode("1+1=2")
    );
    </script>
    En effet, IE ne peut pas ajouter un noed à un objet qui n'a pas fini d'être bindé !

    Sinon, vous avez tjrs document.write qui fait ca mais moi j'aime pas trop donc...

  10. #10
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 665
    Points
    66 665
    Billets dans le blog
    1
    Par défaut
    oui bien sur Fremy nous en étions tous là ...
    il est bien entendu évident qu'en sortant le script de l'objet il n'y a aucun souci ...
    le chalenge était 1 de comprendre la cause de l'erreur et 2 d'arriver à le faire fonctionner sans bouger le script ...

    le plus simple est encore de mettre une fonction dans le head et de la lancer sur le onload ...

  11. #11
    Membre confirmé Avatar de yjuliet
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Août 2006
    Messages
    362
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 362
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par Auteur
    sans doute... Ceci dit je ne considère pas le comportement de IE comme un bug en tant que tel.
    Ce que je considère comme un bug c'est l'erreur retournée, pas le fait que le script provoque une erreur en soi.
    Si il me disait "le noeud n'existe pas, ou n'est pas un objet, ou ...", ça me conviendrait, mais le problème est qu'il me redirige vers une page "server not found" laissant penser à une erreur DNS.
    La solution idéale (pour le cas où l'on serait "obligé" de placer le script inline, est d'utiliser le parametre DEFER qui lance l'exécution du script seulement une fois que l'ensemble de la page est chargée ... au lieu de retarder l'exécution par timeout)

    Je viens de penser à cette solution conne mais efficace (au moins sur IE7 en tout cas)

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

Discussions similaires

  1. [DOM] Ajouter un champ sur élément DOM créer
    Par xillibit dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 08/04/2009, 14h33
  2. [DOM] Ajout d'élément à un fichier XML
    Par pierre24 dans le forum Bibliothèques et frameworks
    Réponses: 11
    Dernier message: 04/03/2008, 15h21
  3. [dom je pense]accéder à des éléments d un tableau sans id
    Par luta dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 07/02/2006, 15h31
  4. [XSL] afficher la valeur d'un élément du noeud parent
    Par luimême dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 08/12/2005, 12h08
  5. Ajout d'attribut à l'élément "Body"
    Par Tirlibibi dans le forum XMLRAD
    Réponses: 2
    Dernier message: 07/04/2003, 15h52

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