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] nodeValue et firstChild pour initialisation de contenu texte


Sujet :

Contribuez

  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] nodeValue et firstChild pour initialisation de contenu texte
    Bonsoir

    Encore un topic/truc pour débutant(e) :

    Context : Soit un paragraphe, que nous appelerons messageArea, dans un document HTML, pour lequel le contenu texte est déterminé à l'execution, et fixé par une procedure JavaScript.

    Ce qui viens d'abord à l'esprit est
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       <p id="messageArea"></p>
    pour l'HTML, puis
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       text = xxxx; // compute anything you want here
       messageArea = document.getElementById('messageArea');
       messageArea.firstChild.nodeValue = text; // <- Erreur d'execution
    pour le code JavaScript.

    Ca a l'air beau, mais ça ne marche pas

    Zut, pourquoi ?

    Raison : Dans le code HTML, aucun texte n'est donné pour l'élément P : normal, puisque notre texte est determiné à l'execution. Ors, pour donner une valeur à un noeud texte, il faut un noeud texte (ça va de soi). Ce noeud texte n'existe pas, puisque l'élément P ne contient rien, et donc l'invocation de firstChild produit une erreur, car le navigateur ne cré pas toujours de noeud texte par défaut vide (Internet Explorer ne le fait pas, par raison d'économie).

    Solution : Le noeud texte ne peut pas être implicite, il faudra donc rendre sont existence explicite. Même si le contenu effectif n'est déterminé qu'à l'execution, il faut donner une valeur à l'élément P, dans le document HTML, pour que le DOM contienne un noeud texte à cet endroit là. On pourra utiliser simplement trois petit point par exemple ("..."). Ces trois petits points conviennent parfaitement à quelque choses qui ne connaitra qu'un bref instant d'affichage, avant d'être initialisé.

    Il faut alors simplement remplacer le code HTML par
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       <p id="messageArea">...</p>
    Le code JavaScript n'est pas en cause dans cette erreur, et il n'y a pas besoin de le modifier.

    Moralité : dans vos documents HTML, destinés à êtres utilisés pour du DHTML, initialisez toujours vos noeuds texte, même si leurs valeurs effectives ne sont determinés qu'à l'execution du programme JavaScript.

    Détail subsidiaire : nous employons messageArea.firstChild.nodeValue, et non pas simplement messageArea.nodeValue, parce que le contenu texte est en fait un noeud enfant... anonyme... mais un noeud enfant quand-même.
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  2. #2
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 681
    Points : 5 221
    Points
    5 221
    Par défaut
    mais pour initialiser la zone dès le chargement, autant créer le paragraphe et son textNode dans la foulée...;

  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 637
    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 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function popul(){
    var text = ' xxxx '; // compute anything you want here
    var    messageArea = document.getElementById('messageArea');
    messageArea.firstChild.nodeValue = text; // <- Erreur d'execution
     }
    </script>
    </head>
     
    <body onload='popul()'>
    ceci fonctionne sans aucun souci chez moi sous IE et FFX

    aussi avec firstChild.data...


    à une condition
    mettre au minimum un contenu au départ dans la balise
    sinon il n'a pas de firstChild ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <p id="messageArea">.</p>
    ou alors le créer dynamiquement et l'appender à la balise
    ce qui se fait en général en une seul étape comme le suggère JT:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     messageArea.appendChild(document.createTextNode(text))}
    et du coup la balise peut être vide
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  4. #4
    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 SpaceFrog
    à une condition
    mettre au minimum un contenu au départ dans la balise
    sinon il n'a pas de firstChild ...
    SpaceFrog.... c'est exactement ce que disait le post justement (c'était un post pour aider les débutant-e-s en DHTML... come moi ... quand je fais une erreure, je la résoud, et j'en parle ici)

    La deuxième solution que tu propose, basée sur appendChild, ne convient pas au cas où l'espace messageArea est modifié plusieurs fois au cours de la vie de la page. Ou alors il faut tester la présence ou non du noeud anonyme. Ne pas avoir à le faire est une petit allégement, et en sus de cela, plus loin, nous verrons pourquoi il est important d'avoir un contenu initial, pour des raisons même autre encore que celle de seulement permettre par là d'avoir un noeud initial.

    Citation Envoyé par JavaTwister
    mais pour initialiser la zone dès le chargement, autant créer le paragraphe et son textNode dans la foulée...;
    Pardon JavaTwister, tu fais erreur, mais au moins ton intervention at-elle le mérite de montrer le mauvais exemple à ne pas suivre (je te taquine ).

    Pourquoi : parce que le design JavaScript doit être conçu à la manière du design CSS, c'est-à-dire en séparant la structure et le comportement, de même que CSS sépare le contenu et la présentation.

    Ainsi, pour cette raison, aucun code JavaScript ne doit être inclus dans les pages (dans l'idéal), peut-être à l'exception notable des code AdSense et autres régie de diffusion publicitaire.

    Séparer le contenu et le comportement.
    Pour utiliser JavaScript, et faire du DHTML propre, en séparant proprement la structure du document et son comportement (document behaviour), il faut seulement donner des attributs id au élément concerné par un comportement quelquonque, puis dans la procédure d'initialisation, attaché les comportement à chaque élément de l'id correspondant (par exemple associer la procédure newDocument à l'élément qui a l'id newDocumentButton)

    Mais me direz-vous, il faut bien pourtant un petit bout de code, ne serait-ce que pour attacher un handler d'événement onload à l'élément body, pour que cette initialisation puisse se faire.

    Hé bien non, même pas Il ne suffit que d'une balise script dans l'entête HTML, avec l'URL du fichier JavaScript. Ce fichier JavaScript contient cette ligne

    Pour mapage.html :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <head>
       <!-- ... -->
       <script type="text/javascript" src="monprograme.js"></script>
       <!-- ... -->
    </head>
    Attention à la balise SCRIPT fermante qui est obligatoire, même si nous n'avons pas de contenu, et seulement des attributs (du moins en HTML, car en XHTML, on peut faire <script ... />, mais je conseil toujours le HTML 4 strict avec éventuellement iframe - en guise d'entorse - plutôt que le XHTML... ceci étant une autre affaire, je ne m'en justifierai pas dans ce fil)

    Pour monprograme.js :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    /* ... */
    window.onload = init; /* init, ou tout autre nom */
    /* ... */
    Attention à la casse de onload : n'écrivez surtout pas onLoad

    Mauvais exemple :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       <body onload="init"> <!-- pas bien -->

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       <body onload="if (truc) chose (); machin (); ..."> <!-- encore pire -->

    Si vous suivez le mauvais exemple, vous n'aurez pas de sucette. Nah!

    Le code qui figure dans le fichier *.js, en dehors de tout corp de fonction, est considéré un peu comme le code contenu entre le BEGIN ... END. d'un programe Pascal ou dans le main d'un programme C

    Il n'y a plus nécéssité d'inclure le moindre bout de code dans le HTML, et il ne reste plus qu'un lien vers le ou les fichiers JavaScript (il peut y en avoir plusieurs, si l'application est complexe, il est plus aisé de répartire les fonctionnalités sur divers fichiers)

    Note : ceci m'a été inspiré par un article sur le site Pompage (mais j'ai perdu l'URL de la page, sorry, I'm so sorry )

    Quel contenu initial ?
    Comme dit dans le topic, et comme rappelé par SpaceFrog, il faut un contenu initial, sinon firstChild n'existe pas. Mais alors quel contenu initial choisir ? Si le contenu initial n'est pas important (il ne s'affiche que transitoirement), il peut être les simples trois petits points dont je parlais. Mais on pourra aussi préférer, surtout si la page doit être référencer par les moteurs de recherche, initialisé avec une petite phrase décrivant le contenu variable (une sorte de de phrase décrivant l'aspect du contenu générique), car les robots d'exploration n'execute que trés rarement le JavaScript.

    Il va de soit, que non seulement cette solution a le mérite de la séparation du contenu et du comportement, mais en plus, elle offre donc un contenu directement utilisable par les robots, ce que ne fait pas la solution d'intégré un code JavaScript d'initialisation du contenu directement dans le code HTML. Car pour les robots, le contenu initial est alors vide, et n'est absolument pas interprétable.

    Il n'y a que du bon à appliquer cette règle de la séparation

    Pourquoi séparer le contenu et le comportement ?
    Réponse : parce que c'est plus crawler-friendly, et même aussi plus user-friendly dans certaines conditions (mais la première raison domine largement). De plus, le code ainsi séparé est plus lisible et plus facile à maintenir (car plus clair, moins brouillon et moins embrouillé), et si vous travailler en équipe, avec répartition des tâche, la personne en charge du HTML n'aura pas à bricoler avec le JavaScript, mais seulement avec des attributs id. Il sera possible, aprés s'être entendu sur les élément et leurs id (on l'aura fait en phase de design ou de spécification), de travailler alors chacun sur sa tâche, sans se marcher sur les pieds ni se nuire mutuellement (éditer un fichier à deux en même temps, n'est pas trés recommendable).


    N.b. Je ne sais pas si j'ai bien fait de répondre ça ici , j'aurais peut-être dut ouvrir un topic exprêt, ... une autre note pour débutant-e ... je laisse à la modération le choix de déplacer ce post, si elle le juge pertinant.
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  5. #5
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 681
    Points : 5 221
    Points
    5 221
    Par défaut
    écoute, c'est proprement phénoménal ce que je viens d'apprendre, là; je suis trop vieux, je vais démissionner

  6. #6
    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 637
    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 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Par défaut
    sans doute un universitaire ?
    c'est pour une thèse ... ?
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  7. #7
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 681
    Points : 5 221
    Points
    5 221
    Par défaut
    en tout cas, c'est tout bien dit: bravo;

  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 637
    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 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Par défaut
    Mais alors du coup ça relève plius de la contribution ...

    Je déplace alors
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    En ce qui me concerne :
    • si je dois ajouter dans ma page un élément (div, a, img, span, form, select, p, table, etc...), j'utilise les fonctions DOM :
      • createElement()
      • appendChild(), insertBefore()
      • removeChild()

    • par contre, je dois l'avouer , si je dois insérer un texte non formaté dans une balise vide (p, div, span, td), j'utilise volontier innerHTML plutôt que createTextNode(). Dans le cas décrit plus haut, c'est à dire l'insertion d'un texte dans un paragraphe vide, j'aurai utilisé sans complexe innerHTML.


    Il faut néanmoins rappeler que l'insertion d'options (balise option) dans un select ou la création de cellules (balises td, tr) dans une table fait appel à d'autres fonctions

  10. #10
    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 Auteur
    [*]par contre, je dois l'avouer , si je dois insérer un texte non formaté dans une balise vide (p, div, span, td), j'utilise volontier innerHTML plutôt que createTextNode(). Dans le cas décrit plus haut, c'est à dire l'insertion d'un texte dans un paragraphe vide, j'aurai utilisé sans complexe innerHTML.
    Oui, c'est vrai, et c'est la façon d'aborder la question qui peut faire toute la différence.

    Si on prend innerHTML comme un moyen d'ajouter des neouds à un élément, alors on se trompe, car appendChild est plus efficace, car il est au niveau implémentation, directement en relation avec le représentation interne du navigateur

    Mais si on veut ajouter un contenu préformaté dans un élément, alors innerHTML est tout à fait justifié, car il est fait pour ça. Exemple : quand on veut introduire du code HTML donné dans une boite de saisie par l'utilisateur/rice, ou encore quand on utilise une fonction renvoyant un texte formaté, plutôt qu'une simple chaîne de caractère (par exemple, une fonction renvoie une chaîne avec certains mots mis en gras... mais la fonction pourrait aprés tout également renvoyer un tableau de noeuds... ce n'est pas interdit)

    La question à sa poser est « que veut-on faire ? »

    Selon que la réponse sera « ajouter un noeud » ou « ajouter du texte préformaté », alors on choisira la première ou la deuxième solution.

    Il y a un exemple que j'aimerais souligner, où l'usage de innerHTML est incontournable :

    Pour bien présenter cet exemple, je vous laisse d'abord penser aux propriétés en écriture, du genre className ou setAttribut (name, value). Il n'existe pas de fonction setTagName, et tagName n'est pas en écriture. Pourtant il arrive que cela soit utile (si le nom de l'élément pouvait être assimilé à un attribut spécial, ce serait bien pratique). Dans ce cas, il n'y a pas d'autre choix que de créer un doublon, en créant un noeud avec createElement(tagName), copier les attributs (ce qui pose un léger problème avec IE, voir plus loin), en les scanant un par un, et ensuite, copier le contenu avec innerHTML (c'est évident dans ce cas là, que scaner les noeuds un par un serait innefficace et pénible, et il est préférable de se reporter à la fonction interne du navigateur, surement plus efficace pour les gros fragments tout entiers).

    La petite note au sujet de IE : les attributs renvoyés par IE inlus les attributs infferés par défaut (comme l'attribut de langue). Ca peut être embétant, parce que le nombre d'attributs qui se trouvent alors dans la copie du noeud, peut être parfois nettement plus important que le nombre d'attributs contenu dans le code (le nombre sera d'autant plus important que le noeud aura un ou des parents qui auront définis des attributs héritables... la copie des attributs ne reflète alors plus du tout la réalité du code).

    Je m'explique : si vous avez dans le source, un noeud <p id="truc>, et que vous voulez changez P en DIV, alors vous créer l'élément DIV, copier le innerHTML de P vers celui de DIV ; mais au moment de copier les attributs, vous devrez lire ceux de P, et là, Internet Explorer ne vous renverra pas seulement l'attribut id, mais également tout un tas d'autres attributs... ce n'est pas trés propre à mon avis... mais bon, ça n'empêche pas l'application de fonctionner non-plus (n.b. ce n'est pas un commentaire pour dire que IE n'est pas bien, parce que j'aime autant IE que les autres.. c'est juste une note comme les autres).
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

Discussions similaires

  1. [DOM] nodeValue et firstChild pour initialisation de contenu texte
    Par Hibou57 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 21/06/2007, 18h41
  2. [Reseau]FTPClient pour afficher le contenu d'un fichier
    Par boxsters dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 21/06/2006, 11h12
  3. [DOM] DOM nodeValue
    Par Mookie dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 23/03/2006, 11h08
  4. XSL : Problème pour visualiser le contenu de <content>
    Par externe dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 31/12/2005, 16h44
  5. Standard XML pour exportation du contenu d'une BDD
    Par Fares BELHAOUAS dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 09/07/2005, 16h03

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