Partage
  • Partager sur Facebook
  • Partager sur Twitter

EventListener d'un objet...

... peut-on le récupérer?

Sujet résolu
    18 mars 2011 à 12:45:27

    (Re-)bonjour à tous,

    J'ai un objet DOM auquel j'ai ajouté un évènement...

    function addListener(node,event,action){
    	node.addEventListener?node.addEventListener(event.replace('on',''),action,false):node.attachEvent(event,action);
    }
    


    Comment puis-je récupérer l'évènement et le code associé, svp?
    • Partager sur Facebook
    • Partager sur Twitter
      18 mars 2011 à 20:25:58

      Un supplément d'explication serait le bienvenu.
      • Partager sur Facebook
      • Partager sur Twitter
        18 mars 2011 à 20:39:08

        Le message qui suit est une réponse automatique activée par un modérateur.
        Les réponses automatiques permettent d'éviter aux modérateurs d'avoir à répéter de nombreuses fois la même chose, et donc de leur faire gagner beaucoup de temps.
        Nous sommes néanmoins ouverts et si vous avez une question ou une remarque, n'hésitez pas à contacter le modérateur en question par MP.


        Description insuffisante du problème


        Bonjour,

        Le modérateur ayant posté ce message estime que vous n'avez pas donné assez d'informations quant à votre problème.
        Afin de faciliter la tâche aux membres qui souhaitent vous aider, il vous est demandé de fournir les erreurs obtenues, ou d'expliquer le comportement inhabituel de votre script. Vous contenter de fournir votre code en disant « ça ne marche pas » n'est pas suffisant.
        Le modérateur vous invite donc à éditer votre message afin de le clarifier.

        Merci de votre compréhension. :)
        Les modérateurs.
        • Partager sur Facebook
        • Partager sur Twitter
        Pwaite.net > Transfert de crédit téléphonique et monétisation de site web                                                                                        « I am awesome »
          19 mars 2011 à 10:30:51

          Hum, je ne vois pas trop ce que je pourrais y dire de plus... je vais donc tenter de le formuler autrement...

          Je voudrais savoir quel est le nom de la propriété dans laquelle les listeners d'une node sont stockées, afin de pouvoir récupérer tous les paramètres passés à ma fonction addListener().

          En gros, j'aimerais pouvoir faire quelque chose comme ceci :

          function addListener(node,event,action){
          	node.addEventListener?node.addEventListener(event.replace('on',''),action,false):node.attachEvent(event,action);
          }
          addListener(document.getElementById('test'),'onclick',function(){alert(1);});
          alert(document.getElementById('test').eventListener.type);
          alert(document.getElementById('test').eventListener.listener);
          alert(document.getElementById('test').eventListener.useCapture);
          
          • Partager sur Facebook
          • Partager sur Twitter
            19 mars 2011 à 11:12:46

            Aaah...

            Euh bah tu peux pas. ^^ Il n'existe pas de tel objet en JS.

            Mais il ne tient qu'à toi de modifier ta fonction pour le créer...
            • Partager sur Facebook
            • Partager sur Twitter
              19 mars 2011 à 11:17:36

              Mais pourquoi ne peut-on pas faire chaque chose que je veux faire? >_<

              Je ne vois pas trop comment modifier ma fonction pour le créer, puisque, sous IE, on ne peut pas toucher à Element... :euh:
              • Partager sur Facebook
              • Partager sur Twitter
                19 mars 2011 à 11:22:46

                function addListener(node,event,action){
                	node.addEventListener?node.addEventListener(event.replace('on',''),action,false):node.attachEvent(event,action);
                	node.eventListener = {
                		type: event,
                		listener: action,
                		useCapture: false
                	};
                }
                
                addListener(document.getElementById('test'),'onclick',function(){alert(1);});
                alert(document.getElementById('test').eventListener.type);
                alert(document.getElementById('test').eventListener.listener);
                alert(document.getElementById('test').eventListener.useCapture);
                

                ? ^^


                Ca dépend de l'utilisation que tu veux en faire, en fait.
                • Partager sur Facebook
                • Partager sur Twitter
                  19 mars 2011 à 11:31:10

                  Ah, désolé, j'étais persuadé que sous IE, ça ne tournerait pas...

                  En fait, l'idée est de pouvoir tester ce qui est dedans, par exemple, pour pouvoir faire une sélection de toutes les nodes ayant un évènement spécifié avec une action spécifiée associée. ;)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 mars 2011 à 11:47:03

                    Ca devrait fonctionner sous IE, car on ne modifie par le prototype de HTMLElement, on ajoute simplement des propriétés à un objet.

                    var events = {};
                    function addEventInfoToNode(node,event,action) {
                    	var nodeInfo = node.eventListener;
                    	if(!nodeInfo) {
                    		nodeInfo = node.eventListener = {types:[]};
                    	}
                    	if(!nodeInfo[event]) {
                    		nodeInfo[event] = [];
                    		nodeInfo.types.push(event);
                    	}
                    	nodeInfo[event].push(action);
                    	if(!events[event]) {
                    		events[event] = [];
                    	}
                    	events[event].push(node);
                    }
                    function getNodesHavingEvent(type) {
                    	return events[type];
                    }
                    function getNodeEventTypes(node) {
                    	return node.eventListener.types;
                    }
                    function getNodeActionsForEvent(node,type) {
                    	return node.eventListener[type];
                    }
                    function addListener(node,event,action){
                    	node.addEventListener?node.addEventListener(event.replace('on',''),action,false):node.attachEvent(event,action);
                    	addEventInfoToNode(node,event,action);
                    }
                    
                    
                    var test = document.getElementById('test');
                    addListener(test,'onclick',function(){alert(1);});
                    	
                    alert(getNodeEventTypes(test)); // ['onclick']
                    alert(getNodeActionsForEvent(test,'onclick')); // [function(){alert(1);}]
                    alert(getNodesHavingEvent('onclick')); // [object HTMLDivElement]
                    
                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 mars 2011 à 0:54:44

                      Merci mais je ne te demandais pas de le coder à ma place... ^^

                      Voici ce que, moi, j'ai fait...

                      <!DOCTYPE html>
                      <html>
                      	<head>
                      	</head>
                      	<body>
                      		<button id="test">test</button>
                      		<script type="text/javascript">
                      function setEvent(type){
                      	this.addedEvents[type].listener?this.addEventListener?this.addEventListener(type,this.addedEvents[type].listener,this.addedEvents[type].useCapture):node.attachEvent('on'+type,this.addedEvents[type].listener):this.removeEventListener?this.removeEventListener(type,this.eventListeners[type].listener,this.eventListeners[type].useCapture):node.detachEvent('on'+type,this.eventListeners[type].listener);
                      	this.eventListeners[type]=this.addedEvents[type];
                      	this.addedEvents[type]={
                      		listener:false,
                      		useCapture:false
                      	};
                      }
                      function addEvent(eventArgs){
                      	if(!this.eventListeners){
                      		this.eventListeners={};
                      		this.addedEvents={};
                      	}
                      	this.addedEvents[eventArgs.type]={
                      		listener:eventArgs.listener||false,
                      		useCapture:eventArgs.useCapture||false
                      	};
                      }
                      function switchEvents(type){
                      	var tempAddedEvents={},prop;
                      	type?tempAddedEvents[type]=this.eventListeners[arguments[0]]||null:tempAddedEvents=this.eventListeners;
                      	this.setEvent=setEvent;
                      	for(prop in tempAddedEvents){
                      		this.setEvent(prop);
                      	}
                      	this.addedEvents=tempAddedEvents;
                      }
                      function getElementsByEventListener(eventArgs){
                      	var i=-1,l=document.getElementsByTagName(eventArgs.tagName||'*').length,checkedElement,elements=[];
                      	while(++i<l){
                      		checkedElement=document.getElementsByTagName(eventArgs.tagName||'*')[i];
                      		if(checkedElement.eventListeners){
                      			if(typeof(eventArgs)=='object'){
                      				if(eventArgs.type&&checkedElement.eventListeners[eventArgs.type]){
                      					if(eventArgs.listener&&typeof(eventArgs.useCapture)=='boolean'&&eventArgs.listener==checkedElement.eventListeners[eventArgs.type].listener&&eventArgs.useCapture==checkedElement.eventListeners[eventArgs.type].useCapture){
                      						elements.push(checkedElement);
                      					}
                      					else if(eventArgs.listener&&eventArgs.listener==checkedElement.eventListeners[eventArgs.type].listener){
                      						elements.push(checkedElement);
                      					}
                      					else if(typeof(eventArgs.useCapture)=='boolean'&&eventArgs.useCapture==checkedElement.eventListeners[eventArgs.type].useCapture){
                      						elements.push(checkedElement);
                      					}
                      					else{
                      						elements.push(checkedElement);
                      					}
                      				}
                      				else if(!eventArgs.type){
                      					if(eventArgs.listener&&eventArgs.listener==checkedElement.eventListeners[eventArgs.type].listener&&typeof(eventArgs.useCapture)=='boolean'&&eventArgs.useCapture==checkedElement.eventListeners[eventArgs.type].useCapture){
                      						elements.push(checkedElement);
                      					}
                      					else if(eventArgs.listener&&eventArgs.listener==checkedElement.eventListeners[eventArgs.type].listener){
                      						elements.push(checkedElement);
                      					}
                      					else if(typeof(eventArgs.useCapture)=='boolean'&&eventArgs.useCapture==checkedElement.eventListeners[eventArgs.type].useCapture){
                      						elements.push(checkedElement);
                      					}
                      				}
                      			}
                      			else if(!eventArgs){
                      				elements.push(checkedElement);
                      			}
                      		}
                      	}
                      	if(elements.length!=0&&eventArgs.index&&/^(-|\d)\d*$/.test(eventArgs.index)){
                      		return /^\d+$/.test(eventArgs.index)?elements[eventArgs.index]:elements[elements.length+eventArgs.index];
                      	}
                      	return elements.length>0?elements:null;
                      }
                      var test=document.getElementById('test');
                      test.addEvent=addEvent;
                      test.switchEvents=switchEvents;
                      test.addEvent({
                      	type:'click',
                      	listener:function(){
                      		alert('cliqué');
                      	}
                      });
                      test.switchEvents('click');
                      alert(getElementsByEventListener({
                      	type:'click',
                      	useCapture:test.eventListeners['click'].useCapture
                      }));
                      		</script>
                      	</body>
                      </html>
                      


                      EDIT : Si vous avez des avis, n'hésitez pas... mais pas taper, heinggg... ^^
                      • Partager sur Facebook
                      • Partager sur Twitter
                        20 mars 2011 à 4:15:42

                        Mon code était juste un exemple :)
                        A toi d'adapter/modifier selon tes besoins ;)
                        • Partager sur Facebook
                        • Partager sur Twitter
                          20 mars 2011 à 10:48:02

                          Oui, je me doute, va... et mici... :)

                          Sinon, que penses-tu du mien?
                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 mars 2011 à 13:08:56

                            Ca me paraît compliqué... J'ai pas compris à quoi servait switchEvents()...

                            Et surtout, j'ai pas compris pourquoi tu fais ça :

                            test.addEvent=addEvent;
                            test.switchEvents=switchEvents;
                            



                            Sinon, ligne 9, tu utilises node pour le detachEvent. Je crois que c'est this que tu voulais mettre...

                            Et ligne 28, tu utilises arguments[0] alors que tu pourrais simplement utiliser type non ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              20 mars 2011 à 13:45:59

                              Merci pour m'avoir fait remarquer les vestiges de mon code initial... (node et arguments[0])

                              En fait, les lignes suivantes
                              test.addEvent=addEvent;
                              test.switchEvents=switchEvents;
                              


                              servent à lier mes méthodes à mon élément DOM, afin de pouvoir utiliser this plutôt que de passer l'élément en paramètre (mais, quand j'aurai fini mon constructeur, ces méthodes en question seront directement liées à mes éléments.

                              Mon switchEvents(), je l'ai créé pour pouvoir définir un deuxième comportement à un élément, sans pour autant qu'il soit actif et pouvoir passer de l'un à l'autre en "sauvegardant" le comportement précédent (d'où la distinction entre addEvent() et setEvent()).

                              Tu n'as jamais eu le cas où, pour un menu déroulant, par exemple, tu devais chaque fois recoder ses évènements, pour l'ouvrir et le refermer?

                              ça se complique vite, quand tu as un menu, sous-menu, sous-sous-menu, etc. qui contiennent des éléments et évènements différents selon si l'utilisateur est identifié ou non, s'il est admin ou user, ..., les fonctions associées au évènements ne sont pas forcément les mêmes.

                              Là, plus besoin de rechercher quels sont les fonctions à exécuter à l'action de l'user, tu le définis juste à la création de l'élément et, ensuite, tu n'as plus qu'à switcher de l'un à l'autre. :)
                              • Partager sur Facebook
                              • Partager sur Twitter
                                20 mars 2011 à 14:08:43

                                Hm... non, je crois que je n'ai jamais rencontré ce cas. :euh:


                                Pour ce qui est d'utiliser this, ce serait plus propre de faire :

                                addEvent.call(test,{
                                	type:'click',
                                	listener:function(){
                                		alert('cliqué');
                                	}
                                });
                                switchEvents.call(test,'click');
                                


                                Ca éviterait les deux affectations useless.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  20 mars 2011 à 14:13:24

                                  Oui, je sais qu'elles sont useless dans le cas présent, il n'en sera pas ainsi dans mon code final... c'était juste pour tester si ça fonctionnait. :)
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  EventListener d'un objet...

                                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                  • Editeur
                                  • Markdown