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 :

Evenement indépendant sur une même classe


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2018
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2018
    Messages : 8
    Par défaut Evenement indépendant sur une même classe
    Bonsoir tout le monde

    Est ce que quelqu'un pourrait m'expliquer pourquoi ce code ne fonctionne pas ? https://codepen.io/anon/pen/LQYXzb

    J'essaie d'appliquer l'évènement suivant à l'élément cliqué et non à toute sa classe, mais sans succès :/

    Merci d'avance !

    Thibault

  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 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    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 659
    Billets dans le blog
    1
    Par défaut
    EN console tu as un message d'erreur :
    info[i] is undefined
    Concentre ta recherche sur les valeurs de i dans la boucle ...


    Mais je te prédis déja un autre souci: l'affectation du onclik ne prend que la dernière valeur de i donc le click n'affectera que le dernier element de la collection.
    Il faut que tu pointes de façon relative sur les enfant de l'élément cliqué.
    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 !

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par SpaceFrog Voir le message
    Mais je te prédis déja un autre souci: l'affectation du onclik ne prend que la dernière valeur de i donc le click n'affectera que le dernier element de la collection.
    Salut,

    Ça fait plusieurs fois que je vois ce problème dans le forum, la dernière fois NoSmoking répondait ici : #3... Il y rappelle le lien :Comment attribuer à des objets un onclick faisant appel à une variable de boucle ?.

    J'aurais une suggestion : rajouter à la fac la solution ES6 avec let que NoSmoking mentionne.

  4. #4
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut


    Exemple en ES2015+ :

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const
    	infos = Array.from( document.querySelectorAll( ".info" ) ),
    	titres = Array.from( document.querySelectorAll( ".titre" ) );
     
    for ( const [ i, titre ] of titres.entries() ){
    	titre.addEventListener( 'click', ev => {
    		infos[i].style.width = '30%';
    		ev.target.style.display = 'none';
    	}, false );
    }

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  5. #5
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    ou plus simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     for(let i=0 ; i<titre.length; i++)

  6. #6
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2018
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2018
    Messages : 8
    Par défaut
    Merci beaucoup ça faisait un moment que ça me posait problème mais je trouvais pas de réponse sur Internet (mauvais mots clés probablement).

    Je commence à peine le js et je connaissais pas d'autres alternatives à var. Merci à tous, j'aurai sûrement pas eu idée d'aller chercher de ce coté ci.

    J'ai en effet remplacer par let, c'est ce qui me semble le plus simple

  7. #7
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    Ok, fallait commencer par la, et dire que tu démarre en javascript, parce sans t"en rendre compte ton problème est un peu vicieux.

    1) l'affectation par let au lieu de var est récente en JavaScript, elle permet de créer une variable à portée locale, mais pas que !!

    dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     .....  titre[i].addEventListener('click', 
        function()  {
            info[i].style.width = '30%';
            this.style.display = 'none';
        }
    la variable i est utilisée bien sur pour créer une fonction pour chaque addEventListener, cad dire qu'il place dans qq part une fonction anonyme mettant ton width à 30% et ainsi de suite.

    mais quand un click survient sur ton objet la valeur de i n'est plus dans le même contexte qu'au moment de l'affextation de tes fonction anonymes et c'est justement l'erreur que tu avais au début par l'utilisation d'une déclaration avec un var

    pour bien le voir, fais ce test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    for( var i=0 ; i<titre.length; i++)
    {
      titre[i].addEventListener('click', 
        function() 
        {
          alert (i);
            info[i].style.width = '30%';
            this.style.display = 'none';
        }
      );
    };
    i=50;
    dans ce code les éléments titre[0] et titre[1] se voient bien dotés d'une fonction annonyme ( mettant width à 30%) mais pour chacune la valeur de i est la même, i=50.

    en passant par un let l'interpréteur javascript crée une variable temporaire qu'il injecte en priorité dans chacune des 2 fonctions anonyme, et c'est une des nouvelle particularité du langage Javascript (ECMA2016)

    Qui ne marche pas sur les anciens interpréteurs JavaScript, comme par exemple sur un FireFox 56 de l'année dernière https://caniuse.com/#search=let

    En javascript tout est objet, quand tu ajoute une propriété à un objet, comme ces 2 fonctions pour chacun des 2 élément, leur contexte d’exécution ne sera pas le même qu'au moment de leur exécution; et tu peux le voir ici avec le alert(i); que j'ai ajouté.

    ou encore, cette fois ci avec un let
    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
    20
    21
    /*Evenement click sur titre*/
     
    var info = document.getElementsByClassName('info');
    var titre = document.getElementsByClassName('titre');
     
    var i =45;
     
    for( let i=0 ; i<titre.length; i++)
    {
      alert ("i pendant la boucle for = " + i);
      titre[i].addEventListener('click', 
        function() 
        {
          alert ("i sur fct d'evt click = " + i);
            info[i].style.width = '30%';
            this.style.display = 'none';
        }
      );
    };
     
    alert ("i  global de fin de code = " + i);
    voila, j’espère que c'est plus clair dans ton esprit maintenant, méfie toi ce genre d'erreur peut être difficile à débusquer, c'est ce que l'on appelle des effets de bords, et c'est une des raisons qui ont poussé à créer des logiques d'encapsulation pour les variables, comme cette nouvelle fonction let, c'est bien plus qu'un un simple problème de portée de variable.

  8. #8
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2018
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2018
    Messages : 8
    Par défaut
    Bonsoir Psychadelic,

    Tout d'abord merci de consacrer ton temps à m'expliquer aussi bien Désolé de te répondre seulement maintenant, je m'attendais pas à recevoir d'autres réponses ^^'

    Je comprends très bien ton explication dans ce cas précis mais j'avoue avoir un peu de mal à comprendre le comportement Js de manière général.

    Jusqu'ici j'avais cru comprendre que les instructions en Js s'appliquaient bêtement une à une.

    Du coup je t'avoue que j'ai du mal à comprendre pourquoi dans le cas présent (avec un var) le programme vient chercher la dernière valeur de i.

    Ce que je veux dire, c'est que dans les fonctionnements algorithmiques de base, à aucun moment le programme ira chercher la dernière valeur

    affectée à une variable pour effectuer un calcul qui a déjà été effectué en plein milieu du programme. Alors pourquoi dans le cas présent, est ce qu'il prend

    la dernière valeure de i ?

    Parce que justement ce n'est pas un calcul ?

    Et du coup j'essaie de visualiser ce que le programme peut bien faire au moment où il parcours le for. Si justement il ne "stocke" pas ces fonctions

    info[0].style.width = '30%'; et info[1].style.width = '30%'; à ce moment là; alors qu'est ce qu'il peut bien faire ?

    Sinon, je te rassure, j'ai très bien compris le fonctionnement du let et son fonctionnement local qui empeche que l'affectation des fonctions soit "perturbé" par la

    valeure de i à la fin. Du coup je me répète mais ce que je comprends pas c'est pourquoi on en a besoin, alors que le programme devrait a mon sens effectué l'attribution

    de i à ces fonctions quand on lui demande de le faire. Pour moi ca defie toute logique. J'espère avoir été assez clair, je t'avoue que c'est un peu compliqué pour moi de mettre des termes

    justes sur tout ca ^^

    Thibault

  9. #9
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    Citation Envoyé par kkelkun Voir le message
    Jusqu'ici j'avais cru comprendre que les instructions en Js s'appliquaient bêtement une à une.
    C'est pas tout à fait comme ça que les choses se présentent.

    Tout d'abord le plus souvent en JavaScript, les fonctions sont appelées à la demande sur des événements indépendants qui peuvent "arriver" dans n'importe quel ordre.

    Par exemple si sur ton interface tu a 2 boutons Disons A et B. avec chacun du code js à réaliser (code_A.js et code_B.js ) tu ne peux pas savoir si à l’avance si ton utilisateur ira cliquer sur le bouton A avant le bouton B, ni combien de fois sur l'un ou l'autre
    donc code_A.js et code_B.js s’exécuteront X fois dans n'importe quel ordre imprévisible.

    cela s'appelle une programmation événementielle.

    Et il y aussi les fonctions asynchrones en JavaScript, qui elles ne se déclencheront pas du tout sagement les unes à la suite des autres, mais c'est une autre histoire.

    ===

    Pour comprendre comment fonctionne l'utilisation des variables, il faut par exemple imaginer une sorte de système de casiers;

    quand tu écris var i = 15; ce que fait l'interpréteur Js c'est d'aller trouver un casier inutilisé, et de lui coller une étiquette avec écrit dessus variable " i " puis de lui mettre une fiche à l'intérieur avec écrit 15 dessus.

    Quand tu donnes l'instruction i = i +1; il va aller rechercher un casier ayant comme étiquette variable "i" comme nom, regarder le chiffre indiqué sur sa fiche et effecteur le calcul demandé, soit effacer la valeur 15 qui y était avant pour la remplacer par la valeur 16.

    De l'autre coté dans ton code tu a demandé une surveillance d'un click sur tes 2 boutons A et B, (avec ta commande addEventListener)
    et a chacun de ces boutons tu y a mis une suite d'instructions, dont l'une est : info[i].style.width = '30%';

    ce qui pour lui signifie aller chercher un casier ayant comme étiquette variable "i" comme nom, prendre sa valeur et l'appliquer sur le Ieme élément nommé info
    quand il exécute cette séquence, il peut y avoir n'importe quoi comme d'écrit sur la fiche du casier " i "

    contrairement à ce que tu penses voici réellement ce que tu à mis dans ton code :

    pour les éléments ( 0 et 1) for( var i=0 ; i<titre.length; i++) (et dans ton exemple titre.length =2)

    donc pour les éléments ayant pour référence titre[0] et titre[1] voici une liste des instructions qu'ils auront a exécuter si jamais l'utilisateur click sur eux =

    récupérer la valeur de la fiche présente du casier i ,
    pour savoir sur lequel des éléments de la liste des objets appelés info
    il devra alors effectuer un changement de style de son width en le mettant à 30%.


    dans ta boucle for( var i=0 ; i<titre.length; i++)
    il commence par mettre zéro sur la fiche du casier i
    il va chercher l'objet titre d'indice i, cad d'indice zero

    sur cet objet il va lui coller la liste d'opérations à réaliser
    il demande à un agent de surveiller une action de "click" sur cet objet pour qu'à ce moment la, il effectue la suite d' instructions qu'il lui a confié.

    Puis il continue sa boucle for, cad dire écrire sur la fiche du casier i la valeur suivante cad i = 1
    prendre l'objet titre[1] lui coller aussi une liste d’opérations à faire avec la même surveillance d'un événement click dessus...

    Puis il continue sa boucle for, cad dire écrire sur la fiche du casier i la valeur suivante cad i = 2
    la il se rends compte que la valeur de i n'est plus inférieure à titre.length
    et il en reste la , en laissant dans le casier 'i' une fiche avec écrit dessus la valeur 2.

    et qui d'ailleurs est susceptible d'être modifié par la suite; j'y avais mis 50 dans mon exemple.

    et c'est cette valeur de fiche que retrouveront les deux éléments ayant pour référence titre[0] et titre[1] lors que surviendra sur eux un "click"...


    Ce type de comportement n'est pas propre au langage JavaScript, il est propre à tous les langages quand ils sont utilisés de manière "dynamique" ou disons événementielle.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 09/12/2015, 11h58
  2. Réponses: 3
    Dernier message: 23/03/2015, 11h12
  3. Réponses: 1
    Dernier message: 02/10/2011, 17h30
  4. Réponses: 3
    Dernier message: 16/10/2003, 10h22
  5. capter l'evenement clic sur une cellule d'un string grid
    Par lasconic dans le forum Composants VCL
    Réponses: 3
    Dernier message: 25/06/2003, 10h51

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