2009-09-29 3 views
117

Que se passe-t-il si je lie deux gestionnaires d'événements au même événement pour le même élément?jQuery: plus d'un gestionnaire pour le même événement

Par exemple:

var elem = $("...") 
elem.click(...); 
elem.click(...); 

Est-ce que le dernier gestionnaire "gagner", ou seront les deux gestionnaires être exécuté?

Répondre

141

Les deux gestionnaires courront, le modèle d'événement jQuery permet à plusieurs gestionnaires sur un élément, donc un gestionnaire plus tard ne remplace pas un gestionnaire plus.

The handlers will execute in the order in which they were bound.

+1

que se passe-t-il avec la façon native? et comment le natif sait-il comment supprimer un spécifique? – SuperUberDuper

+1

Selon le DOM niveau 3 (référence à la spécification HTML 5), les gestionnaires d'événements sont exécutés dans l'ordre dans lequel ils sont enregistrés - http://www.w3.org/TR/DOM-Level-3-Events/#event-phase et http://www.w3.org/TR/2014/REC-html5-20141028/webappapis.html#event-handler-attributes. Les gestionnaires d'événements peuvent être supprimés en transmettant une référence au gestionnaire qui a été enregistré –

+0

@RussCam que se passe-t-il si un même gestionnaire est lié plus d'une fois suffit de dire 'jQuery ('. Btn'). On ('click', handlerClick); 'est appelé à divers endroits sans réellement' .off' il anywher? –

2

Les deux gestionnaires sont appelés.

Vous pouvez penser à inline event binding (par exemple "onclick=..."), où un grand inconvénient est qu'un seul gestionnaire peut être défini pour un événement.

jQuery est conforme à la DOM Level 2 event registration model:

Le DOM modèle d'événement permet l'enregistrement d'événements multiples auditeurs sur un seul EventTarget. Pour y parvenir, les écouteurs d'événements ne sont pas stockées plus comme des valeurs d'attribut

+0

savez-vous dans quel ordre? –

+0

@Rich: la commande est officiellement indéfinie. –

33

Supposons que vous ayez deux gestionnaires, f et g, et que vous voulez vous assurer qu'ils sont exécutés dans un ordre, puis juste les encapsuler connues et fixes:

$("...").click(function(event){ 
    f(event); 
    g(event); 
}); 

De cette façon il n'y a (du point de vue de jQuery) que un gestionnaire, qui appelle f et g dans l'ordre spécifié.

+3

+1, l'encapsulation à l'intérieur d'une fonction est la voie à suivre. Et une meilleure logique conditionnelle peut être contenue à l'intérieur de la fonction gestionnaire pour contrôler le ou les événements déclenchés. –

+0

C'est mieux dans MHO – Sydwell

+0

Une collection de gestionnaires dont la séquence est déterminée par programme. –

8

Vous devriez pouvoir utiliser enchaînant pour exécuter les événements dans l'ordre, par exemple:

$('#target') 
    .bind('click',function(event) { 
    alert('Hello!'); 
    }) 
    .bind('click',function(event) { 
    alert('Hello again!'); 
    }) 
    .bind('click',function(event) { 
    alert('Hello yet again!'); 
    }); 

Je suppose que le code ci-dessous fait la même

$('#target') 
     .click(function(event) { 
     alert('Hello!'); 
     }) 
     .click(function(event) { 
     alert('Hello again!'); 
     }) 
     .click(function(event) { 
     alert('Hello yet again!'); 
     }); 

Source: http://www.peachpit.com/articles/article.aspx?p=1371947&seqNum=3

TFM dit aussi:

Lorsqu'un événement atteint un élément, tous les gestionnaires liés à cet événement type pour l'élément sont déclenchés. Si plusieurs gestionnaires sont enregistrés, ils s'exécutent toujours dans l'ordre dans lequel ils se trouvaient . Une fois tous les gestionnaires exécutés, l'événement se poursuit le long du chemin de propagation d'événement normal .

+1

Ni ce code ni cet article ne définissent un ordre d'exécution du gestionnaire. Oui, c'est l'ordre dans lequel l'événement * binding * se produira, mais l'ordre que les gestionnaires d'événements reçoivent est toujours officiellement indéfini. –

+0

hein?Qu'en est-il "Maintenant, lorsque l'événement click se produit, le premier gestionnaire d'événements sera appelé, suivi par le second, suivi par le troisième." n'est pas clair? – anddoutoi

+0

et oui, je sais que les recs officiels ne définissent pas cela et PPK a déjà prouvé que l'exécution de l'événement est aléatoire, mais peut-être jQuery a fixé ce ^^ – anddoutoi

1

Il existe une solution de contournement pour garantir qu'un gestionnaire se produise après l'autre: attachez le deuxième gestionnaire à un élément conteneur et laissez l'événement exploser. Dans le gestionnaire attaché au conteneur, vous pouvez regarder event.target et faire quelque chose si c'est celui qui vous intéresse.Brut, peut-être, mais ça devrait certainement fonctionner.

2

Fait fonctionner avec succès en utilisant les 2 méthodes: l'encapsulation de Stephan202 et les écouteurs d'événements multiples. J'ai 3 onglets de recherche, nous allons définir leur id texte d'entrée est dans un tableau:

var ids = new Array("searchtab1", "searchtab2", "searchtab3"); 

Lorsque le contenu des changements de searchtab1, je veux mettre à jour searchtab2 et searchtab3. At-il ainsi pour l'encapsulation:

for (var i in ids) { 
    $("#" + ids[i]).change(function() { 
     for (var j in ids) { 
      if (this != ids[j]) { 
       $("#" + ids[j]).val($(this).val()); 
      } 
     } 
    }); 
} 

écouteurs d'événements multiples:

for (var i in ids) { 
    for (var j in ids) { 
     if (ids[i] != ids[j]) { 
      $("#" + ids[i]).change(function() { 
       $("#" + ids[j]).val($(this).val()); 
      }); 
     } 
    } 
} 

J'aime les deux méthodes, mais le programmeur a choisi l'encapsulation, mais les écouteurs d'événements multiples ont également travaillé. Nous avons utilisé Chrome pour le tester.

16

feux .bind() de jQuery dans l'ordre qu'il était lié:

Lorsqu'un événement atteint un élément, tous les gestionnaires liés à cet événement type pour l'élément sont tirés. Si plusieurs gestionnaires sont enregistrés, ils s'exécutent toujours dans l'ordre dans lequel ils se trouvaient . Une fois tous les gestionnaires exécutés, l'événement se poursuit le long du chemin de propagation d'événement normal .

Source: http://api.jquery.com/bind/

Parce que d'autres fonctions de jQuery (. L'ex .click()) sont des raccourcis pour .bind('click', handler), je suppose qu'ils sont également déclenchés dans l'ordre dans lequel ils sont liés.

Questions connexes