Quelle est la différence entre «on» et «live» ou «bind»?

172

Dans jQuery v1.7, une nouvelle méthode a onété ajoutée. De la documentation:

'La méthode .on () attache des gestionnaires d'événements à l'ensemble d'éléments actuellement sélectionné dans l'objet jQuery. Depuis jQuery 1.7, la méthode .on () fournit toutes les fonctionnalités requises pour attacher des gestionnaires d'événements. '

Quelle est la différence avec liveet bind?

Diego
la source
Avait cherché quelque chose comme ça avant de demander et n'a pas réussi. Merci!
Diego

Réponses:

329

on()est une tentative de fusionner la plupart des fonctions de liaison d'événements de jQuery en une seule. Cela a l'avantage supplémentaire de rangement de l'inefficacité avec livevs delegate. Dans les futures versions de jQuery, ces méthodes seront supprimées et seulement onet oneresteront.

Exemples:

// Using live()
$(".mySelector").live("click", fn);

// Equivalent `on` (there isn't an exact equivalent, but with good reason)
$(document).on("click", ".mySelector", fn);
// Using bind()
$(".mySelector").bind("click", fn);

// Equivalent `on`
$(".mySelector").on("click", fn);
// Using delegate()
$(document.body).delegate(".mySelector", "click", fn);

// Equivalent `on`
$(document.body).on("click", ".mySelector", fn);

En interne, jQuery mappe toutes ces méthodes et les setters de gestionnaire d'événements abrégés à la on()méthode, indiquant en outre que vous devez désormais ignorer ces méthodes et utiliser simplement on:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},
delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

Voir https://github.com/jquery/jquery/blob/1.7/src/event.js#L965 .

Andy E
la source
Comme @JamWaffles l'a dit, la réponse la plus compréhensible. Pourriez-vous s'il vous plaît ajouter la comparaison entre on et déléguer pour compléter la réponse? Merci!
Diego
lols, vous avez ajouté la source jquery 4 secondes avant moi: D btw live contexte équivalent est document, pas document.body
Esailija
1
Vous voudrez peut-être faire référence à la balise 1.7 à la place, sinon des modifications futures pourraient rendre votre lien invalide (ne pas pointer vers le bon emplacement): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling
3
$(document.body).delegate("click", ".mySelector", fn);devrait être$(document.body).delegate(".mySelector", "click", fn);
Sonny
2
@dsdsdsdsd, off sert de remplacement générique pour unind, unive et un undelegate.
Andy E
12

onest dans la nature très proche de delegate. Alors pourquoi ne pas utiliser le délégué? C'est parce que onça ne vient pas seul. il y a off, pour dissocier l'événement et onepour créer un événement à exécuter une seule fois. Il s'agit du "package" d'un nouvel événement.

Le principal problème de liveest qu'il s'attache à "window", forçant un événement de clic (ou un autre événement) sur un élément au plus profond de la structure de la page (le dom), à "remonter" en haut de la page pour trouver un événement gestionnaire disposé à y faire face. À chaque niveau, tous les gestionnaires d'événements doivent être vérifiés, cela peut s'additionner rapidement, si vous faites une imbrication profonde ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

Alors, bindcomme click, comme les autres classeurs d'événements de raccourci se fixent directement sur la cible de l' événement. Si vous avez un tableau de, disons, 1000 lignes et 100 colonnes, et chacune des 100'000 cellules comprend une case à cocher que vous souhaitez gérer. Joindre 100'000 gestionnaires d'événements prendra beaucoup de temps lors du chargement de la page. La création d'un seul événement au niveau de la table et l'utilisation de la délégation d'événements sont plusieurs ordres de grandeur plus efficaces. La cible de l'événement sera récupérée au moment de l'exécution de l'événement. " this" sera la table, mais " event.target" sera votre " this" habituel dans une clickfonction. Maintenant, ce qui onest bien avec, c'est que " this" sera toujours la cible de l'événement, et non le conteneur auquel il est attaché.

Roselan
la source
Le délégué n'est-il pas accompagné d'un non-délégué?
DaveWalley
1
Ouaip. bon repérage. Vous apprenez tous les jours;) (Le doc s'est grandement amélioré depuis 2011)
roselan
5

avec la .onméthode il est possible de faire .live, .delegateet .bindavec la même fonction mais avec .live()seulement .live()c'est possible (déléguer des événements au document).

jQuery("#example").bind( "click", fn ) = jQuery( "#example").on( "click", fn );

jQuery("#example").delegate( ".examples", "click", fn ) = jQuery( "#example" ).on( "click", ".examples", fn )

jQuery("#example").live( fn ) = jQuery( document ).on( "click", "#example", fn )

Je peux le confirmer directement à partir de la source jQuery:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

jQuery (this.context)? this.context=== documentdans la plupart des cas

Esailija
la source
3

(Ma phrase d'ouverture avait plus de sens avant que vous ne changiez la question. À l'origine, vous aviez dit "Quelle est la différence avec live?")

onc'est plus comme delegateça que c'est comme live, c'est fondamentalement une forme unifiée de bindet delegate(en fait, l'équipe a dit que son but est "... d'unifier toutes les façons de joindre des événements à un document ..." ).

liveest fondamentalement on(ou delegate) attaché au document dans son ensemble. Il est obsolète à partir de la v1.7 au profit de l'utilisation de onou delegate. À l'avenir, je suppose que nous verrons du code utilisant onuniquement, plutôt que d'utiliser bindou delegate(ou live) ...

Ainsi, en pratique, vous pouvez:

  1. Utilisez oncomme bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
  2. Utilisez onlike delegate(délégation d'événement enracinée dans un élément donné):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
  3. Utilisez onlike live(délégation d'événement enracinée dans le document):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);
TJ Crowder
la source
1
Dans la page que j'ai liée, il est dit "Si un nouveau code HTML est injecté dans la page, sélectionnez les éléments et attachez les gestionnaires d'événements une fois le nouveau code HTML placé dans la page. Ou utilisez des événements délégués pour attacher un gestionnaire d'événements, comme décrit ci-après." . Donc, il est plus probable de se lier, pas de vivre. Ai-je raison?
Diego
@Diego: onest une combinaison de bindet delegate, et comme je l'ai dit, pas vraiment live. Vous pouvez utiliser onlike bind(attacher un gestionnaire directement à un élément), ou vous pouvez utiliser onlike delegate(attacher un gestionnaire à un élément, mais déclencher l'événement uniquement si l'élément réel sur lequel vous avez cliqué correspond à un sélecteur, et comme si cet élément était celui le événement s'est produit sur - par exemple, délégation d'événement), ou vous pouvez l'utiliser comme live(en delegateutilisant le document comme racine). C'est la délégation d'événements qui le rend utile si vous ajoutez des éléments de manière dynamique.
TJ Crowder
1
l'ancien live pouvait aussi être utilisé comme délégué: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );En fait, dans l'ancienne source jQuery, ils utilisaient live comme cas général et délégué comme cas particulier, ce qui rendait cela encore plus déroutant quand on y réfléchit.
Esailija
@Esailija: Très bien. Je ne pense pas que ce soit l'utilisation pour laquelle il s'est fait connaître, car ils ont été ajoutés delegaterapidement, mais quand même. :-)
TJ Crowder
2

live est le raccourci pour .on () maintenant

//from source http://code.jquery.com/jquery-1.7.js
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
}

aussi ce message peut être utile pour vous http://blog.jquery.com/2011/11/03/jquery-1-7-released/

doochik
la source
2

Il n'y en a pas pour le cas d'utilisation de base. Ces deux lignes sont fonctionnellement identiques

$( '#element' ).bind( 'click', handler );
$( '#element' ).on( 'click', handler );

.on () peut également effectuer une délégation d'événements, et est préférable.

.bind () est en fait juste un alias pour .on () maintenant. Voici la définition de la fonction bind en 1.7.1

bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},

L'idée d'ajouter .on () était de créer une API d'événement unifiée, plutôt que d'avoir plusieurs fonctions pour lier l'événement; .on () remplace .bind (), .live () et .delegate ().

Dan
la source
0

Quelque chose que vous devez savoir si vous voulez que les gestionnaires d'événements soient associés à l'élément - faites attention à quel élément le gestionnaire était attaché!

Par exemple, si vous utilisez:

$('.mySelector').bind('click', fn);

vous obtiendrez les gestionnaires d'événements en utilisant:

$('.mySelector').data('events');

Mais si vous utilisez:

$('body').on('click', '.mySelector', fn);

vous obtiendrez les gestionnaires d'événements en utilisant:

$('body').data('events');

(dans le dernier cas, l'objet événement concerné aura selector = ". mySelector")

Alexandre
la source
eventsest de toute façon non documenté et je pense que cela ne fonctionne plus dans la version 1.9
John Dvorak
Droite. On peut utiliser _data au lieu de données dans les versions plus récentes. La réponse concernait la différence dans le "propriétaire de l'événement" plutôt que la syntaxe exacte pour les anciennes ou nouvelles versions. Il existe d'autres articles sur la syntaxe exacte des différentes versions de JQuery. Par exemple stackoverflow.com/questions/2518421/…
Alexander