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 :

Création d'une treeview


Sujet :

JavaScript

  1. #1
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut Création d'une treeview
    Bonjour,

    Je ne suis pas novice en programmation mais je suis novice en javascript. je suis en train de mettre en place un "treeview" pour m'exercer et pour mon site ( site de cours de maths en ligne pour la période de confinement)
    Voici l'extrait de mon code qui pose souci:
    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
    function addListeners(){
        let carets= tree.getElementsByClassName("caret");
        for (let i=0;i<carets.length;i++){
            carets[i].addEventListener("click", function(){
                this.classList.toggle("caret-down")          
                let nestedElements =this.querySelectorAll("ul > li")
                console.log(nestedElements)            
                for (let i=0;i<nestedElements.length;i++){
                nestedElements[i].classList.toggle("active")
     
                }
            });
        }
    }

    La ligne qui pose souci est celle-ci: let nestedElements =this.querySelectorAll("ul > li") .

    Avec mon console.log, je vois que tous les éléments enfants "li" sont ciblés alors que je ne veux cibler que ceux qui sont les enfants directs. Il me semblait que le sélecteur CSS "ul>li" permettait de faire cela mais je ne trouve pas de solution à mon problème. Merci d'avance pour vos éventuelles aides.

    Raphaël, enseignant.

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 955
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 955
    Points : 44 103
    Points
    44 103
    Par défaut
    Bonjour,
    ton sélecteur fait ce qu'il faut, il cible les <li> enfants directs d'un élément <ul> ce qui est (devrait être) toujours le cas mais il semblerait que cela soit le premier <ul> que tu cherches à cibler, mais il nous manque donc ta structure HTML pour te montrer.

  3. #3
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut suite avec code HTML
    merci tout d'abord d'avoir pris du temps pour cette première réponse.
    Ce sont bien les li directs sous le ul que je cherche à cibler. Voici le code HTML qui va avec:
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <nav id="navTree">
            <ul>
                <li> Classe de seconde
                    <ul>
                        <li><a href="#">Chapitre 1</a>
                            <ul>
                                <li>doc 1</li>
                                <li>doc 2</li>
                            </ul>
                        </li>
                        <li><a href="#">Chapitre 2</a>
                            <ul>
                                <li>doc 1</li>
                                <li>doc 2</li>
                            </ul>
                        </li>
     
                    </ul>
                </li>
                <li> Classe de premiere
                    <ul>
                        <li><a href="#">Chapitre 1</a>
                            <ul>
                                <li>doc 1</li>
                                <li>doc 2</li>
                            </ul>
                        </li>
                        <li><a href="#">Chapitre 2</a>
                            <ul>
                                <li>doc 1</li>
                                <li>doc 2</li>
                            </ul>
                        </li>
     
                    </ul>
                </li>
            </ul>

    À noter que les classes n'apparaissent pas dans le code HTML: la première partie de mon script js se charge de les ajouter et cela, ça marche ( vérification faite avec l'inspecteur d'élément)

    Merci d'avance pour une éventuelle réponse

  4. #4
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Citation Envoyé par rafoim Voir le message

    Avec mon console.log, je vois que tous les éléments enfants "li" sont ciblés alors que je ne veux cibler que ceux qui sont les enfants directs.
    C'est ce qui est fait, tu as bien les enfants directs mais de tous les ul...

  5. #5
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut merci
    Merci bien, je vais chercher comment cibler les "li" du premier niveau de mon arborescence. Je reviendrai chercher votre précieuse aide si je coince trop. En attendant, j'ai mis le sujet sur "résolu" car mon erreur d'interprétation a bien été corrigée.

  6. #6
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par rafoim Voir le message
    À noter que les classes n'apparaissent pas dans le code HTML: la première partie de mon script js se charge de les ajouter et cela, ça marche ( vérification faite avec l'inspecteur d'élément)

    Merci d'avance pour une éventuelle réponse
    Question un peu hors sujet mais, si tu as un script capable de cibler les bons éléments pour leur ajouter une classe, alors à quoi sert la classe ?

    Pour répondre à ta question, techniquement le sélecteur ul > li est équivalent à li tout court car un élément <li> est toujours un descendant direct de <ul>.
    Le détail qui nous manque encore, dans ton code, c’est à quel endroit sont ajoutées les classes "caret". En fonction de l’élément de départ (this) sur lequel est appliqué querySelectorAll, le résultat ne sera pas le même.
    Si ça peut t’aider, sache que tu peux naviguer vers le haut dans l’arbre DOM avec la propriété .parentElement ou la méthode .closest().

    Une autre piste de solution : tu peux essayer de ne mettre que l’instruction this.classList.toggle("caret-down") dans ta fonction, et t’arranger pour que les éléments voulus apparaissent en utilisant uniquement du code CSS
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  7. #7
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut
    Je te cite:
    " Question un peu hors sujet mais, si tu as un script capable de cibler les bons éléments pour leur ajouter une classe, alors à quoi sert la classe ? "
    Je m 'inspire en fait de la méthode ici:https://www.w3schools.com/howto/howto_js_treeview.asp

    j'ai voulu modifier un peu. je n'ai pas encore testé mais je crois que leur méthode ne fonctionne que si on est dans une totale imbrication des répertoires et des sous-répertoires, pas pour un arbre plus général ( deux entrées de niveau supérieures par exemple).

    je tente aussi de modifier une chose: je ne veux pas avoir à écrire les classes dans mon html d'où l'insertion par js. Voici le script complet avec la fonction qui insère les classes:
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    function prepareTree(){
     
        let treeElements = tree.getElementsByTagName("li")
     
        for (let i=0;i<treeElements.length;i++){
            let l = treeElements[i].children.length
            if (l>0){
                treeElements[i].classList.add("caret")
            }
     
            if (treeElements[i].parentElement.parentElement.tagName != "NAV" ){
                treeElements[i].classList.add("nested")
            }
        }
    }
     
    function addListeners(){
        let carets= tree.getElementsByClassName("caret");
        for (let i=0;i<carets.length;i++){
            carets[i].addEventListener("click", function(){
                this.classList.toggle("caret-down")          
                let nestedElements =this.querySelectorAll("ul > li")
                console.log(nestedElements)            
                for (let i=0;i<nestedElements.length;i++){
                nestedElements[i].classList.toggle("active")
     
                }
            });
        }
    }
    let tree = document.getElementById("navTree");
    prepareTree();
    addListeners();


    Mon code insère les classes puis les classes doivent s'ajouter ou se soustraire selon les événements. je n'ai pas compris pourquoi tu trouvais cela inutile ( j'ai senti une pointe d'ironie par contre, mais il n'y a pas de souci).
    pour la navigation avec parentElement, je vais y penser. Le souci, c'est que quand je remonte au parent, ensuite, je risque de sélectionner trop de monde ( je sais, ce n'est pas très clair).

    merci pour ta participation à ma recherche.

    Raphaël

  8. #8
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Watilin Voir le message
    ...techniquement le sélecteur ul > li est équivalent à li
    Oui et non, soyons précis :
    • ul > li signifie : les li "descendants directs" de ce ul.
    • li cible "tous les li", où et quels qu'ils soient.

    Certes, ul > li (sans plus de précision) est équivalent à li.

    Mais, selon cette configuration :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <ul id="menu">
      <li>..... menu 1
        <ul>
          <li>..... sous-menu 1.1</li>
          <li>..... sous-menu 1.2</li>
        </ul>
      </li>
      <li>..... menu 2</li>
    </ul>

    Pour cibler les "bons" <li>, on doit indiquer de quel <ul> on parle :
    • ul#menu > li ne cible QUE les menus (car "descendants directs"), mais PAS les sous-menus.
    • Pour cibler les sous-menus, on peut utiliser ul#menu > li > ul > li (sous-menus de niveau 1), ul#menu ul > li (tous les sous-menu, quel que soit leur niveau, sous-sous-menu,...)
    Dernière modification par Invité ; 06/04/2020 à 14h52.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Cela dit... pour corriger ton code :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    "use strict";
    const tree = document.getElementById("navTree");
     
    prepareTree(tree); // remarque : au cas où on peut avoir plusieurs "trees", on passe le "tree" en paramètre des fonctions.
    addListeners(tree);
     
    function prepareTree(tree)
    {
      let tree_elts = tree.querySelectorAll("li");
      tree_elts.forEach( elt => {
        if( elt.querySelector("ul") ) // si on a un sous-menu (présence de ul dans le li)
        {
          elt.classList.add("caret"); // ajoute "caret" au li
          elt.querySelector("ul").classList.add("nested"); // ajoute "nested" au ul enfant du li
        }
      });
    }
     
    function addListeners(tree)
    {
      var togglers = tree.querySelectorAll(".caret");
      togglers.forEach( elt => {
        elt.addEventListener("click", function(event) {
          event.stopPropagation(); // IMPORTANT (stoppe la propagation de l évènement)
          this.querySelector("ul.nested").classList.toggle("active");
          this.classList.toggle("caret-down");
        });
      }); 
    }

  10. #10
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 955
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 955
    Points : 44 103
    Points
    44 103
    Par défaut
    Pourquoi faire « compliqué » et ne pas plutôt cibler les <ul> qui si ils sont enfants d'un <li> ils ne sont pas à la racine et donc « expandable ».

    J'avais fait un truc comme
    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
    /**
     * Gestion expand/collapse
     */
    const elementsUL = document.querySelectorAll("ul");
    elementsUL.forEach((el) => {
      const parent = el.parentNode;
      if( "LI" === parent.tagName){
        const oBtn = document.createElement("BUTTON");
        oBtn.className = "btn-close";
        parent.appendChild( oBtn);
        oBtn.addEventListener("click", (e) => {
          e.stopPropagation();
          parent.classList.toggle("collapse");
        });
      }
    });
    avec un soupçon de CSS sur les boutons

  11. #11
    Invité
    Invité(e)
    Par défaut
    @NoSmoking,

    si tu suis le lien donné en référence, tu verras que les classes "caret", "nested" ont déjà leur CSS.

    D'où l'intérêt de les ajouter dynamiquement (sans besoin de créer de nouveaux élements du DOM)

    Ça donne: https://codepen.io/jreaux62/pen/BaNXyMd

    Remarque : la différence avec le modèle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <li><span class="caret">Beverages</span>
    Ici, on met la classe directement sur le <li>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <li class="caret">Beverages
    Dernière modification par Invité ; 06/04/2020 à 17h01.

  12. #12
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 955
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 955
    Points : 44 103
    Points
    44 103
    Par défaut
    Citation Envoyé par jreaux62
    (sans besoin de créer de nouveaux élements du DOM)
    parce que dans l'exemple fourni il n'y a pas d'élément superflus comme les <span> !

    Citation Envoyé par rafoim
    je tente aussi de modifier une chose: je ne veux pas avoir à écrire les classes dans mon html d'où l'insertion par js. Voici le script complet avec la fonction qui insère les classes:
    c'est à cela que sert l'utilisation du JavaScript, de tout faire d'un coup, et ce en une seule fonction.

  13. #13
    Invité
    Invité(e)
    Par défaut
    @NoSmoking
    Ben justement... on est d'accord, non ?

    • code HTML minimum (sans <span>, ni classes)
    • JS qui "fait le job" (avec une seule fonction)

    Je poste le code (simplifié) de mon exemple : https://codepen.io/jreaux62/pen/BaNXyMd
    (au cas où je supprime - plus tard - mon Codepen)

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    <nav id="navTree">
      <ul>
        <li> Classe de seconde
          <ul>
            <li><a href="#">Chapitre 1</a>
              <ul>
                <li>doc 1</li>
                <li>doc 2</li>
              </ul>
            </li>
            <li><a href="#">Chapitre 2</a>
              <ul>
                <li>doc 1</li>
                <li>doc 2</li>
              </ul>
            </li>
     
          </ul>
        </li>
        <li> Classe de premiere
          <ul>
            <li><a href="#">Chapitre 1</a>
              <ul>
                <li>doc 1</li>
                <li>doc 2</li>
              </ul>
            </li>
            <li><a href="#">Chapitre 2</a>
              <ul>
                <li>doc 1</li>
                <li>doc 2</li>
              </ul>
            </li>
     
          </ul>
        </li>
      </ul>
    </nav>
    Code css : 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     /* Remove default bullets */
    ul, #navTree {
      list-style-type: none;
    }
     
    /* Remove margins and padding from the parent ul */
    #navTree {
      margin: 0;
      padding: 0;
    }
     
    /* Style the caret/arrow */
    .caret {
      cursor: pointer;
      user-select: none; /* Prevent text selection */
    }
     
    /* Create the caret/arrow with a unicode, and style it */
    .caret::before {
      content: "\25B6";
      color: black;
      display: inline-block;
      margin-right: 6px;
    }
     
    /* Rotate the caret/arrow icon when clicked on (using JavaScript) */
    .caret-down::before {
      transform: rotate(90deg);
    }
     
    /* Hide the nested list */
    .nested {
      display: none;
    }
     
    /* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */
    .active {
      display: block;
    }
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    "use strict";
    // ----------
    // au chargement de page
    window.addEventListener('DOMContentLoaded', function(){
      const tree = document.getElementById("navTree");
      setTreeView(tree); // remarque : au cas où on peut avoir plusieurs "trees", on passe le "tree" en paramètre
    });
    // ----------
    function setTreeView(tree)
    {
      let tree_elts = tree.querySelectorAll("li");
      tree_elts.forEach( elt => {
        if( elt.querySelector("ul") ) // si on a un sous-menu (présence de ul dans le li)
        {
          elt.classList.add("caret"); // ajoute "caret" au li
          elt.querySelector("ul").classList.add("nested"); // ajoute "nested" au ul enfant du li
        }
      });
      let togglers = tree.querySelectorAll(".caret");
      togglers.forEach( elt => {
        elt.addEventListener("click", function(event) {
          event.stopPropagation(); // IMPORTANT (stoppe la propagation de l évènement)
          this.querySelector("ul.nested").classList.toggle("active");
          this.classList.toggle("caret-down");
        });
      }); 
    }
    /* --------- */
    VARIANTE (version "Objet") :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    "use strict";
    // ----------
    // au chargement de page
    window.addEventListener('DOMContentLoaded', function(){
      const tree = document.getElementById("navTree");
      TreeView.init(tree); // on passe le "tree" en paramètre
    });
    // ----------
    // Définition de l objet
    var TreeView = {
    	// --------
    	// Initialisation
    	init:function(tree)
    	{
        let tree_elts = tree.querySelectorAll("li");
        tree_elts.forEach( elt => {
          if( elt.querySelector("ul") ) // si on a un sous-menu (présence de ul dans le li)
          {
            elt.classList.add("caret"); // ajoute "caret" au li
            elt.querySelector("ul").classList.add("nested"); // ajoute "nested" au ul enfant du li
          }
        });
        let togglers = tree.querySelectorAll(".caret");
        togglers.forEach( elt => {
          elt.addEventListener("click", function(event) {
            event.stopPropagation(); // IMPORTANT (stoppe la propagation de l évènement)
            this.querySelector("ul.nested").classList.toggle("active");
            this.classList.toggle("caret-down");
          });
        }); 
      }
    	// --------
    };
    // ----------
    Dernière modification par Invité ; 06/04/2020 à 17h37.

  14. #14
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 955
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 955
    Points : 44 103
    Points
    44 103
    Par défaut
    Citation Envoyé par jreaux62
    Ben justement... on est d'accord, non ?
    Certes mais sur la façon d'y arriver, je trouve plus simple de cibler les éléments <ul> plutôt que <li>, ce qui te permet d'avoir un code plus concis.
    Ce que je trouvais compliqué était surtout le fait qu'une fois un élément trouvé on ne l'utilise pas complétement et qu'il faille faire deux boucles pour arriver à ses fins.

    En prenant les classes utilisées dans ton exemple cela donnerait si je ne me trompe pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const elementsUL = document.querySelectorAll("ul");
    elementsUL.forEach((el) => {
      const parent = el.parentNode;
      if ("LI" === parent.tagName) {
        el.classList.add("nested")
        parent.className = "caret";
        parent.addEventListener("click", (e) => {
          e.stopPropagation();
          parent.classList.toggle("caret-down");
          el.classList.toggle("active");
        });
      }
    });
    je pense même qu'il y aurait moyen de mettre les deux classes, nested et caret, sur le même élément.

  15. #15
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    je pense même qu'il y aurait moyen de mettre les deux classes, nested et caret, sur le même élément.



  16. #16
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par rafoim Voir le message
    je n'ai pas compris pourquoi tu trouvais cela inutile ( j'ai senti une pointe d'ironie par contre, mais il n'y a pas de souci).
    C’était une vraie question, désolé si ça sonnait ironique, ce n’était pas mon intention. L’information que je n’avais pas était celle-ci :
    je ne veux pas avoir à écrire les classes dans mon html
    … Ce qui est une raison parfaitement valable.

    Je souligne juste un point délicat dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            if (treeElements[i].parentElement.parentElement.tagName != "NAV" ){
    Ici, tu as un enchaînement .parentElement.parentElement qui est « rigide » et cassera dès la première modification de la structure HTML. Ok, tu n’as sans doute pas prévu de modifier le HTML, et je comprends l’intention de remonter exactement 2 niveaux. Mais en l’occurence, je pense qu’on peut se passer complètement de la classe "nested" en la remplaçant, à la fois dans le code CSS et dans le code JS, par un simple sélecteur ul ul. Je sais que je contredis W3Schools (ça ne sera pas la première fois )

    pour la navigation avec parentElement, je vais y penser. Le souci, c'est que quand je remonte au parent, ensuite, je risque de sélectionner trop de monde ( je sais, ce n'est pas très clair).
    Si si ça me semble clair Bien sûr, rien ne t’empêche de combiner des trucs comme .parentElement.querySelectorAll( ... ).

    Ah, une précision peut-être utile : quand tu écris this.querySelectorAll("ul > li"), le sélecteur CSS n’est pas limité au sous-arbre de this. Je m’explique : pour résoudre un querySelectorAll, le moteur JS fait deux choses :
    1. il établit la liste des enfants de l’élément ciblé ;
    2. il invoque le moteur de filtrage CSS pour tester le sélecteur "ul > li" sur chacun des enfants.

    Le moteur CSS n’a pas connaissance de « l’élément de base » de querySelectorAll, et il peut remonter plus haut si besoin quand il y a une relation de descendance à tester.
    Par exemple, this.querySelectorAll("nav li") fonctionne parce qu’il y a un élément <nav> plus haut dans l’arbre, même si c’est au-dessus de l’élément this.

    Citation Envoyé par jreaux62 Voir le message
    (au cas où je supprime - plus tard - mon Codepen)
    Je te remercie d’avoir pensé au “link rot”
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  17. #17
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2013
    Messages : 38
    Points : 47
    Points
    47
    Par défaut merci encore
    merci pour toutes les idées que vous m'avez données. La lecture de vos conseils et de vos débats va me prendre du temps.
    Ne pensez-vous pas qu'il serait préférable de renommer ce fil avec un titre comme " bâtir un treeview en javascript"?
    Pour d'autres que cela intéresserait bien sûr.
    Bonne soirée.

    Raphaël

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

Discussions similaires

  1. [Débutant] Création et utilisation d'une treeView
    Par Gonzague54 dans le forum Développement Windows
    Réponses: 1
    Dernier message: 06/09/2019, 17h34
  2. [Plugin][View][TreeView] Création d'une vue.
    Par bitou dans le forum Eclipse Platform
    Réponses: 6
    Dernier message: 20/11/2007, 12h57
  3. Création d'une base avec IbConsole
    Par Lucien dans le forum Outils
    Réponses: 3
    Dernier message: 02/03/2004, 18h34
  4. création d'une batabse .gdb
    Par jejestyle dans le forum Bases de données
    Réponses: 3
    Dernier message: 23/02/2004, 00h29
  5. [BES] Création d'une variable d'environnement
    Par NGI80 dans le forum Autres
    Réponses: 2
    Dernier message: 17/10/2002, 07h31

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