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 :

Comportement inattendu gestionnaire "addEventListener" sur event "click" avec this.id


Sujet :

JavaScript

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Novembre 2018
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Novembre 2018
    Messages : 13
    Points : 5
    Points
    5
    Par défaut Comportement inattendu gestionnaire "addEventListener" sur event "click" avec this.id
    Bonjour à tous,
    D'abord, j’ai très peu d’expérience en JS (la théorie seulement). En fait, j’essaie de faire ma première page dynamique en JS.

    Mon objectif est de déplier (développer) un élément du DOM en sous éléments (children) lorsque je click sur cet élément parent.
    - Si je click une premiere fois sur l'élément parent "niveau1", je le développe en affichant un children "niveau2"que je créé dynamiquement en JS.
    - Si je click sur l'élément parent une seconde fois alors qu'il est déjà déplier/développé, alors je supprime les children (je referme le dépliage). Cette partie là est commentée dans mon code pour le moment)
    - Ma fonction "developpe" est également en mesure de développer un children en sous-children ("niveau3", je me suis arrêté là pour l’instant.

    J’utilise la méthode "addEventListener" sur l’élément et je passe 2 parametres :
    - "click"
    - ma fonction "developpe" avec "this.id"

    Le dépliage du "niveau1" se passe correctement. En revanche au dépliage du "niveau2", je constate deux appels à ma fonction "developpe" :
    - un premier avec un "this.id" qui vaut "niveau2" (donc je déplie le "niveau2" en affichant "niveau3" tout va bien).
    - un second qui vient dans la foulée avec un "this.id" qui vaut "niveau1" et que je n’attends pas puisque je n’ai pas cliqué sur "niveau1"

    C’est en positionnant un console.log() dans ma fonction "developpe" que j’ai vu ce qu’il se passait.

    Nom : trace.png
Affichages : 282
Taille : 135,1 Ko

    Je pense que j’ai mal interprété quelque chose et que je n’emploie pas le gestionnaire d’évènements "addEventListener" dans les règles.
    Mais là je suis sec, je ne vois pas comment m’en sortir. J’ai fourni le code en pièce jointe. Pouvez-vous jeter un œil et me donner un piste pour avancer.

    Merci à tous

    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
     
    <!DOCTYPE html>
    <html>
        <head>
            <!-- En-tête de la page -->
            <meta charset="utf-8" />
            <title>Titre</title>
     
        </head>
     
     
        <body>
            <h1 id="titre">Titre</h1>
            <div>
                <script src="./developper.js"></script>            
            </div>
     
        </body>
    </html>

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    function developpe(valId) {
        var elt = document.getElementById(valId);
        var eltChildLength = elt.childNodes.length;
     
        switch (valId)
        {
            case "niveau1":
                var list=["niveau2"];
                break;
            case "niveau2": 
                var list=["niveau3"];
                break;
        }
        console.log('click sur ' + valId);
        console.log('demande un developpement du niveau "' + valId + '", donc affichage de "' + list[0] + '" sur la page web');
        // Si le niveau selectionne n'a pas d'enfants alors il faut déplier en créant des enfants 
        if (eltChildLength <= 1) {
     
            listLength = list.length;
            for (var i = 0; i < listLength; i++) {
                var subElt = document.createElement("h1"); // Création d'un sous élément de balise "h1"
                subElt.id = list[i]; // Définition de son identifiant
                subElt.setAttribute("onmouseover", 'this.style.cursor=\'pointer\';');
                subElt.style.fontSize = "14px";
                subElt.addEventListener("click", function () { developpe(this.id); } );
                subElt.innerHTML = list[i];
                elt.appendChild(subElt); // Insertion du nouveau sous-élément
            }
     
            // Si le niveau selectionnee a des enfants alors on supprime les enfants pour replier le niveau
            } else {
                var children = elt.childNodes;
                //for ( var i = eltChildLength - 1; i >= 1; i-- ) {
                //  elt.removeChild(children[i]);
                //}
     
            }
     
     
    }
     
    // Main: Affichage de la page d'accueil "niveau1"
    var elt = document.createElement("h1"); // Création d'un élément de balise "h1"
    elt.id = "niveau1"; // Définition de son identifiant
    elt.setAttribute("onmouseover", 'this.style.cursor=\'pointer\';');
    elt.innerHTML = "niveau1";
    elt.style.fontSize = "14px";
    elt.addEventListener("click", function () { developpe(this.id); } );
    document.getElementById("titre").appendChild(elt);

  2. #2
    Invité
    Invité(e)

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Novembre 2018
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Novembre 2018
    Messages : 13
    Points : 5
    Points
    5
    Par défaut OK: stopPropagation
    Merci pour le coup de main jreaux62, je vais creuser cette piste.

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

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 889
    Points : 3 728
    Points
    3 728
    Par défaut
    Salut,

    C'est un exercice ou bien tu veux faire un site ?

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Novembre 2018
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Novembre 2018
    Messages : 13
    Points : 5
    Points
    5
    Par défaut Exercie ou site
    Bonjour Beginner,

    A terme, effectivement, je veux me faire un petit site.
    En résumé, je veux pouvoir interroger ma page web depuis mon tel portable et consulter différentes données que j'aurai auparavant stocker dans une base mysql.

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

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 889
    Points : 3 728
    Points
    3 728
    Par défaut
    Salut,

    1- Dans l'autre fil tu parles de "viande" est-ce juste un exemple ou bien tu comptes faire un site sur la viande ?

    2- As-tu résolu ton problème ?

    3- Est-ce qu'il y a beaucoup d’articles ? Parce que là je vois que tu fabriques ton menu et sous-menu dynamiquement alors que tu pourrais faire une liste avec des balises <ul> et <li> auxquelles tu ajouterais la fonctionnalité "plier/déplier". En plus c'est étrange tu utilises des balises <h1> imbriquées...

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Novembre 2018
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Novembre 2018
    Messages : 13
    Points : 5
    Points
    5
    Par défaut Précisions
    Salut,

    1 - Non, dans mon précédent fil ce n'était pas un exemple. Je ne fais pas un site sur la viande non plus. Je souhaite référencer pour différents types d'aliment le prix auquel je les trouve en faisant les courses. Ainsi, au bout d'un moment je pourrai vérifier si une offre est effectivement intéressante. C'est un peu simplet, mais cela me permettra de me faire la main sur différents outils de développement web en réalisant quelque chose qui m'est utile.

    2 - oui, avec la piste que m'a fourni jreaux62, j'ai modifié l'appel à ma fonction "developpe" (faite dans le addEventListener). Ainsi, j'ai pu faire un event.stopPropagation dans cette fonction et obtenir le fonctionnement que j'attendais sur ma page. Je suis conscient que le code est sans doute maladroit et sujet à beaucoup d'améliorations. Dans l'immédiat, j'ai fait quelque chose que je comprenais et avec l'expérience je vais découvrir des bonnes pratiques que je mettrais en oeuvre bien entendu. Voici ce que j'ai fais:
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    function developpe(event) {
        event.stopPropagation();
        var valId = this.id;
        var elt = document.getElementById(valId);
        var eltChildLength = elt.childNodes.length;
     
        switch (valId)
        {
            case "niveau1":
                var list=["niveau2"];
                break;
            case "niveau2": 
                var list=["niveau3"];
                break;
        }
     
        // Si le niveau selectionne n'a pas d'enfants alors il faut déplier en créant des enfants 
        if (eltChildLength <= 1) {
     
            listLength = list.length;
            for (var i = 0; i < listLength; i++) {
                var subElt = document.createElement("h1"); // Création d'un sous élément de balise "h1"
                subElt.id = list[i]; // Définition de son identifiant
                subElt.setAttribute("onmouseover", 'this.style.cursor=\'pointer\';');
                subElt.style.fontSize = "14px";
                subElt.addEventListener("click", developpe);
                subElt.innerHTML = list[i];
                elt.appendChild(subElt); // Insertion du nouveau sous-élément
            }
     
            // Si le niveau selectionnee a des enfants alors on supprime les enfants pour replier le niveau
            } else {
                var children = elt.childNodes;
                for ( var i = eltChildLength - 1; i >= 1; i-- ) {
                  elt.removeChild(children[i]);
                }
     
            }
     
     
    }
     
    // Main: Affichage de la page d'accueil "niveau1"
    var elt = document.createElement("h1"); // Création d'un élément de balise "h1"
    elt.id = "niveau1"; // Définition de son identifiant
    elt.setAttribute("onmouseover", 'this.style.cursor=\'pointer\';');
    elt.innerHTML = "niveau1";
    elt.style.fontSize = "14px";
    elt.addEventListener("click", developpe);
    document.getElementById("titre").appendChild(elt);

    3 - Oui, oui, tu as raison, il faudra que j'utilise des balises genre <ul> et <li>. Malheureusement, je ne maîtrise pas encore assez html et javascript pour gérer tout de suite le design. Je me focalise sur la partie fonctionnelle, ensuite j'attaquerai la "deco".

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Citation Envoyé par ManuZaz Voir le message
    ...D'abord, j’ai très peu d’expérience en JS (la théorie seulement)...
    Le code que tu écris n'est pas totalement inutile puisque tu apprends des choses...
    Par contre c'est totalement absurde !

    Pourquoi créer les menus "à la volée" en JavaScript ??
    Ça n'a absolument aucun intérêt d'un point de vue "pratique"... Et ça complique inutilement le script.

    On peut très bien écrire le menu en HTML (DANS le code HTML), et faire apparaitre les niveaux au clic via JS.


    N.B. <ul><li> : ce n'est pas qu'une question de "design".
    Il s'agit aussi de "sémantique" (<ul><li> signifie "liste non ordonnées").
    Et, généralement, les menus sont construits ainsi.

    ET (toujours pour la sémantique), on entoure le menu d'une balise <nav> (= "navigation").

    Exemple :
    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
    <h1 id="titre">Menu</h1> 
    <nav>
      <ul id="mon-menu">
        <li>Menu 1
          <ul>
            <li>Menu 1.1
              <ul>
                <li>Menu 1.3</li>
                <li>xxx</li>
                <li>yyy</li>
              </ul>
            </li>
            <li>Menu 1.2
            </li>
          </ul>
        </li>
        <li>Menu 2
          <ul>
            <li>Menu 2.1
              <ul>
                <li>Menu 1.3</li>
                <li>zzz</li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </nav>
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    #mon-menu ul { display:none; } /* masque les sous-menu */
    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
    'use strict';
    var id_menu = 'mon-menu';
    var les_li = document.querySelectorAll( '#'+id_menu+' li' );
     
    les_li.forEach( function( le_li ){
      le_li.addEventListener('click', function( event ){
        event.stopPropagation();
        console.log(le_li.childNodes);
        if ( le_li.hasChildNodes() ) 
        {
          var ul = le_li.childNodes[1]; // cible le ul
          ul.style.display = (ul.style.display == 'block')? 'none':'block';
        }
      });
    })

    Remarque importante :
    jQuery permet de grandement SIMPLIFIER la SYNTAXE.
    Dernière modification par Invité ; 11/11/2018 à 18h12.

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Novembre 2018
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Novembre 2018
    Messages : 13
    Points : 5
    Points
    5
    Par défaut "niveau1" contenu dans une bdd mysql
    Bonjour,

    - Merci pour le event.stopPropgation, cela m'a bien dépanné
    - J'ai bien compris pour le <nav>, <ul> et <li>, je vais faire propre dès le départ
    - Le code fourni est un testcase minimal destiné à mettre en évidence le phénomène de propagation que je rencontrais et ne comprenais pas
    Mon menu sera composé de différents éléments de "niveau1". Ces éléments sont extraits d'une table mysql parce que le nombre d'éléments de "niveau1" pourra varier (suppression, ajout, renommage etc...)
    Quand vous dites "On peut très bien écrire le menu en HTML (DANS le code HTML), et faire apparaitre les niveaux au clic via JS.", est-ce que cela est appliquable dans le cas où les éléments de "niveau1" du menu ne sont statiques?

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Novembre 2018
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Novembre 2018
    Messages : 13
    Points : 5
    Points
    5
    Par défaut merci pour les exemple des code
    Bonsoir jreaux62,

    J'ai répondu un peu trop tôt dans le post précédent, je n'avais pas, alors, l'intégralité de votre réponse (les exemples de code n’étaient pas visibles).
    Merci beaucoup de la peine que vous êtes donné pour me rédiger cet exemple.

  11. #11
    Invité
    Invité(e)
    Par défaut
    Le menu HTML peut évidemment être généré en PHP, à partir des données d'une bdd.

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Novembre 2018
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Novembre 2018
    Messages : 13
    Points : 5
    Points
    5
    Par défaut Cloture
    J'ai tous les éléments qui me sont nécessaires pour aller un peu plus loin

    Merci jreaux62

    Je clos cette discussion.

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

Discussions similaires

  1. Comportement inattendu de Callback sur pushbutton
    Par Rakanishu dans le forum Interfaces Graphiques
    Réponses: 5
    Dernier message: 27/02/2013, 16h48
  2. Problème sur Request.ServerVariables("QUERY_STRING"
    Par PrinceMaster77 dans le forum ASP
    Réponses: 3
    Dernier message: 25/03/2005, 11h47

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