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 :

Plusieurs addEventListener, seul le dernier fonctionne


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de speedev
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 051
    Par défaut Plusieurs addEventListener, seul le dernier fonctionne
    Bonjour,

    Je rencontre un problème que j'ai déjà résolu mais impossible de retrouver la solution.

    Le code génère plusieurs boutons radios depuis une boucle For() et affecte à chacun un événement de souris ("click" en l'occurrence).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    // on se trouve dans une boucle For()
    // des IDs sur chaque boutons radios sont bien créés (vérifié)
    // et enfin une affectation d'événement simple ci-dessous
     
    document.getElementById("radio_"+id).valeur = valeur;
    document.getElementById("radio_"+id).addEventListener("click", function () {
          alert(this.valeur);
    }, false);
     
    // Fin de la boucle
    Mon problème :
    L'alert javascript ne fonctionne que sur le dernier bouton radio créé.
    Il y a donc un écrasement des événements similaires précédemment créés (vu sur https://developer.mozilla.org/fr/DOM...dEventListener) mais je ne trouve plus comment y remédier.

    Merci de votre aide

  2. #2
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Salut,

    Tu pourrai donner un peu plus de code, parce que cela semble correct ton extrait.

  3. #3
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    si tu es dans une boucle pourquoi ne pas faire directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    document.getElementById("radio_"+id).onclick = function(){alert(this.valeur);};

  4. #4
    Membre éprouvé Avatar de speedev
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 051
    Par défaut
    Parce que ça non plus ça ne marche pas, j'ai testé DOM0, DOM1 et DOM2

  5. #5
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    mouai donc le problème vient d'ailleurs
    montre nous un peu plus ton code

  6. #6
    Membre éprouvé Avatar de speedev
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 051
    Par défaut
    Je vous ai réécris le code en grande partie avec des copier-coller, je ne garanti pas les fautes de frappes ni l'indentation du code...mais ça devrait vous éclairer un peu.

    En gros, je récupère un flux XML stocké dans la variable "t_con".
    Je parcours les noeuds un peu sauvagement (il y a surement plus optimisé comme technique) mais je suis obligé de faire vite et avec mes connaissances surement limitées...

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    for(i=0;i<t_con[0].childNodes.length;i++)
    {	
    	var code	="";
    	var valeur	="";
    	var node = t_con[0].childNodes[i];
    	if (node.nodeType == 1)
    	{
    		if(node.firstChild)
    		{
    			switch(node.nodeName)
    			{
    				case "PARENT" :
    					// init de variables
    					for(j=0;j<node.childNodes.length;j++)
    					{
    						var enfant = node.childNodes[j];
    						if (enfant.nodeType == 1)
    						{
    							if(enfant.firstChild)
    							{
    								switch(enfant.nodeName)
    								{
    									case "CODE" : code = enfant.firstChild.nodeValue;
    									break;
    									case "VALEUR" : valeur = enfant.firstChild.nodeValue;
    									break;
    									//etc...
    								}
    							}
    						}			
    					}			
    					document.getElementById("radio_"+code).valeur = valeur;
    					addEvent("radio_"+code,"click", function () {
    						alert('ok');	
    						document.getElementById("conteneur_de_valeur").innerHTML = this.valeur;
    						// Je stocke la variable "valeur" dans un div lorsque je clique sur le bouton radio correspondant à son code associé
    					}, false);
    				break;
    			}
    		}
    	}								
    }

  7. #7
    Membre éprouvé Avatar de speedev
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 051
    Par défaut
    Excusez...voici la fonction addEvent...
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    function addEvent(objid,ev,fnc,capt){
    	var obj = document.getElementById(objid);
    	if(obj.addEventListener)
    	{
    		obj.addEventListener(ev, fnc, capt);
    	}
    	else if(obj.attachEvent)
    	{
    		obj.attachEvent(
    			'on'+ev,
    			function()
    			{
    				return fnc.apply(obj, arguments);
    			}
    		);
    	}
    	else
    	{
    		if(!obj['on'+ev])
    		{
    			obj['on'+ev] = fnc;
    		}
    		else
    		{	
    			var oldfnc = obj['on'+ev];
    			obj['on'+ev] = function(){
    				oldfnc();
    				fnc();
    			}
    		}
    	}
    	return true;
    }

  8. #8
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut


    trève de plaisanterie :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <div id="mesCheck">
    	<input type="checkbox"><input type="checkbox"><input type="checkbox"><input type="checkbox"><input type="checkbox">
    </div>
    <script type="text/javascript">
    	var listCheck = document.getElementById('mesCheck').getElementsByTagName('input');
    	for(var i = 0  , l = listCheck.length ; i <l  ; i++){
    		if(listCheck[i].type == 'checkbox'){
    			listCheck[i].valeur = "je vaux : " + i ;
    			listCheck[i].onclick = function(){alert(this.valeur)};
    		}
    	}
    </script>
    fais un copier coller de ce code dans une page
    tu seras en bonne voie pour comprendre ton problème

  9. #9
    Membre éprouvé Avatar de speedev
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 051
    Par défaut
    Je comprends bien ton code mais il ne me sert à rien.
    J'emploie cette méthode sur d'autres dév mais ce n'est pas le cas ici.

  10. #10
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    c'est un exemple pour te montrer que l'erreur ne vient pas de l'assignation de l'évènement mais du code plus haut ...

    1 chose a vérifier : que ton objet existe bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function addEvent(objid,ev,fnc,capt){
    	var obj = document.getElementById(objid);
            alert(obj);
    ...
    si oui , le problème viendra de la méthode addevent

  11. #11
    Membre éprouvé Avatar de speedev
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 051
    Par défaut
    Encore cette matinée sur le problème.
    Je ne comprends pas du tout où ça bloque, tous mes IDs existent quand il le faut mais le addEventListener n'est toujours affecté que sur le dernier élément radio créé.

    J'ai testé qlq closures javascript mais elles n'arrangent rien.

    Je reste à votre écoute si vous pouvez m'aider, en attendant je passe à autre chose, ça fait 2 jours perdus déjà...

  12. #12
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Salut,

    Tu aurai pu faire un peu plus court, mais c'est pas grave.

    Ton problème est le suivant:

    tu utilise liste.innerHTML += "....";

    ce qui se traduit par liste.innerHTML = liste.innerHTML + "....";

    Donc tu relis le contenu html de liste sous forme de chaine, tu ajoute le nouveau
    code et tu écrase le innerHTML à nouveau.

    Dans cette opération tu perds les noeuds dom sur lesquels tu as assigné
    tes évènements, de nouvelles instances sont recrées à partir de la chaine.

    Seule la dernière assignation d'évènement subsiste.

    Tu devrais plutôt utiliser document.createElement et createTextNode pour
    fabriquer tes inputs, ton texte et ton br

    et surtout liste.appendChild(...) à chaque fois, ainsi tu ajoute au dom sans
    supprimer les éléments déjà crées.

  13. #13
    Membre éprouvé Avatar de speedev
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 051
    Par défaut
    Mince...honnêtement je fermais les yeux sur le innerHTML car véritablement dans mon code j'ai plusieurs DIV et classes CSS qui m'imposent pas mal de createElement de setAttribute en tout genre etc... (un code beaucoup plus long donc) et comme j'étais pressé je suis passé par un innerHTML ne pensant pas sur le coup que ça perturberait les choses.

    Au final j'ai perdu plus de temps avec cette foutue innerHTML...ça m'apprendra.

    Merci.

  14. #14
    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
    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 !

  15. #15
    Membre éprouvé Avatar de speedev
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 051
    Par défaut
    Je confirme que c'est OK avec les DOMs, merci Marcha...

    Intéressant ton dev SpaceFrog, je vais me pencher la dessus dès que possible.

    De mon côté, c'était vraiment de la "feignasserie" car j'ai codé le tout en DOM en qlq minutes... J'ai horreur d'être comme ça mais c'est de famille (vive les Bretons !)

    Avouez que c'est tentant le innerHTML pour faire court...voici le code qui remplace la ligne de code fautive :

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    var _DIV = document.createElement("DIV");	_DIV.className="container_rc";			_DIV.setAttribute('onmouseover','this.style.backgroundColor=\'#fff\';');_DIV.setAttribute('onmouseout','this.style.backgroundColor=\'#f5f5f5\';');
    var _TABLE = document.createElement("TABLE");
    var _TBODY = document.createElement("TBODY");
    var _TR = document.createElement("TR");
    var _TD1 = document.createElement("TD");
    _TD1.style.width = "20px";
    _TD1.className = "c";									
    try{  
    	_RAD = document.createElement('<input type="radio" name="chp_code" value="'+code+'" />');  
    }catch(bug){  
    	_RAD = document.createElement('input');  
    	_RAD.setAttribute('type','radio');  
    	_RAD.setAttribute('name','chp_code'); 
    	_RAD.setAttribute('value',code);
    }  
    	_RAD.id = code_relais; 
    	_RAD.code = code;
    	_RAD.valeur= valeur;
     
    	addEvent(_RAD,"click", function () {
    		alert(code+" "+valeur);
    	}, false);
     
    	_TD1.appendChild(_RAD);
           var _TD2 = document.createElement("TD");
    	_TD2.innerHTML = "<span style=\"font-weight:bold\">"+code_relais+"</span><br />"+code+" - "+valeur+"</div><div class=\"clear\">";
    	_TR.appendChild(_TD1);
    	_TR.appendChild(_TD2);
    	_TBODY.appendChild(_TR);
    	_TABLE.appendChild(_TBODY);
     
    	liste.appendChild(_TABLE);

  16. #16
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    speedev, tu devrais t'intéresser à des Framework si tu aimes vraiment
    la "feignasserie" :-)

    Deux d'entre eux devraient t'aider si tu fais beaucoup de choses
    similaires à ton post.

    Ma préférence pour celui-ci: Jquery
    ou prototype suivant les goûts.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 22/02/2010, 11h58
  2. Réponses: 0
    Dernier message: 01/07/2009, 10h40
  3. VHOST Seule la premiere fonctionne
    Par Guillomme dans le forum Apache
    Réponses: 2
    Dernier message: 07/03/2008, 14h43
  4. [DOM] Seul le dernier élément est affiché
    Par COLOMBAT dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 21/12/2007, 18h12
  5. Réponses: 6
    Dernier message: 15/03/2007, 10h29

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