web-dev-qa-db-fra.com

jquery .live ('click') vs .click ()

Je me demande s’il existe des circonstances dans lesquelles il serait préférable d’utiliser .click(function {...}); plutôt que .live('click', function {...});?

D'après ce que je comprends, l'option live semble être une meilleure option et je l'utilise donc dans presque toutes les circonstances à la place du simple .click (), d'autant plus que beaucoup de mon code est chargé de manière asynchrone.

EDIT: Une autre partie de cette question. Si je charge tout le javascript de manière asynchrone, .click récupérera toujours tous les éléments déjà présents dans le domaine. Droite?

57
kalpaitch

Il peut arriver que vous souhaitiez explicitement affecter uniquement le gestionnaire de clics à des objets existants et gérer les nouveaux objets différemment. Mais le plus souvent, vivre ne fonctionne pas toujours. Cela ne fonctionne pas avec les instructions jQuery chaînées telles que:

$(this).children().live('click',doSomething);

Il a besoin d’un sélecteur pour fonctionner correctement en raison de la façon dont les événements remontent dans l’arborescence DOM.

Edit: Quelqu'un vient d'augmenter sa voix, alors évidemment, les gens la regardent encore. Je devrais souligner que live et bind sont tous les deux obsolète . Vous pouvez effectuer les deux avec .on() , dont la syntaxe est beaucoup plus claire. Pour remplacer bind:

$(selector).on('click', function () {
    ...
});

et pour remplacer live:

$(document).on('click', selector, function () {
    ...
});

Au lieu d'utiliser $(document), vous pouvez utiliser n'importe quel objet jQuery contenant tous les éléments sur lesquels vous surveillez les clics, mais l'élément correspondant doit exister lorsque vous l'appelez.

133
Nathan MacInnes

(Note 29/08/2017:live était obsolète depuis plusieurs versions et supprimé dans la v1.9. delegate était déconseillé dans la v3.0. Dans les deux cas, utilisez la signature de délégation de on à la place [également couvert ci-dessous].)


live se produit en capturant l'événement lorsqu'il est remonté du DOM jusqu'à la racine du document, puis en regardant l'élément source. click se produit en capturant l'événement sur l'élément lui-même. Ainsi, si vous utilisez live et qu'un des éléments ancêtres accroche directement l'événement (et l'empêche de continuer à bouillonner), vous ne verrez jamais l'événement sur votre élément. Alors que normalement, l'élément le plus proche de l'événement (click ou autre) est saisi en premier, le mélange d'événements live et non -live peut changer cela de manière subtile.

Par exemple:

jQuery(function($) {

  $('span').live('click', function() {
    display("<tt>live</tt> caught a click!");
  });

  $('#catcher').click(function() {
    display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});
<div>
  <span>Click me</span>
  <span>or me</span>
  <span>or me</span>
  <div>
    <span>I'm two levels in</span>
    <span>so am I</span>
  </div>
  <div id='catcher'>
    <span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span>me too</span>
  </div>
</div>
<!-- Using an old version because `live` was removed in v1.9 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>

Je vous recommande d'utiliser delegate over live lorsque vous le pouvez, pour pouvoir contrôler plus en profondeur la portée; avec delegate, vous contrôlez l'élément racine qui capture l'événement de propagation (par exemple, live est fondamentalement delegate en utilisant la racine du document comme racine). Nous vous recommandons également d'éviter (dans la mesure du possible) d'avoir delegate ou live en interaction avec la gestion des événements non déléguée et non en direct.


Ici, plusieurs années plus tard, vous n’utiliseriez ni live ni delegate; vous utiliseriez la signature de délégation de on, mais le concept est toujours le même: l'événement est accroché à l'élément que vous appelez on on, mais n'est déclenché que lorsque les descendants correspondent au sélecteur donné après le nom de l'événement:

jQuery(function($) {

  $(document).on('click', 'span', function() {
    display("<tt>live</tt> caught a click!");
  });

  $('#catcher').click(function() {
    display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});
<div>
  <span>Click me</span>
  <span>or me</span>
  <span>or me</span>
  <div>
    <span>I'm two levels in</span>
    <span>so am I</span>
  </div>
  <div id='catcher'>
    <span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span>me too</span>
  </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

12
T.J. Crowder

Tous les objets qui seraient associés au .click doivent exister lorsque vous définissez l'événement.

Exemple: (en pseudo-code) l'ajout peut être $("body").append() par exemple

append('<div id="foo" class="something">...</div>');
$("div.something").click(function(){...});
append('<div id="bar" class="something">...</div>');

Click fonctionne pour foo mais ne fonctionne pas pour bar

Exemple2:

append('<div id="foo" class="something">...</div>');
$("div.something").live("click",function(){...});
append('<div id="bar" class="something">...</div>');

click fonctionne pour foo et bar

Avec .live ("clic" ..., vous pouvez ajouter dynamiquement plus d'objets après avoir créé l'événement. Cet événement continuera de fonctionner.

10
fmsf

"live" est nécessaire lorsque vous générez du code de manière dynamique . Regardez juste l'exemple ci-dessous:

$("#div1").find('button').click(function() {
    $('<button />')
     .text('BUTTON')
     .appendTo('#div1')
})
$("#div2").find('button').live("click", function() {
    $('<button />')
     .text('BUTTON')
     .appendTo('#div2')
})
button {
  margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id="div1">
  <button>Click</button>
</div>
<div id="div2">
  <button>Live</button>
</div>

sans "live", l'événement de clic ne se produit que lorsque vous cliquez sur le premier bouton; avec "live", l'événement de clic se produit également pour les boutons générés dynamiquement 

5
Mr. Black

Utilisez toujours click si vous n’ajoutez pas d’éléments de manière dynamique.

live fonctionne en ajoutant un écouteur d'événement à la racine du document et en écoutant les événements bouillonnés. Une alternative est delegate , qui fonctionne de la même manière, mais lie le gestionnaire d’événements à l’élément spécifié.
De cette façon, l'événement ne doit pas faire apparaître tout le DOM et est capturé plus tôt.

4
Felix Kling

.live () est utilisé si des éléments sont ajoutés après le chargement initial de la page. Supposons que vous ayez un bouton ajouté par un appel AJAX après le chargement de la page. Ce nouveau bouton ne sera pas accessible avec .click (), vous devrez donc utiliser .live ('click')

3
dotty

Comme 'live' gérera les événements pour les éléments futurs qui correspondent au sélecteur actuel, vous pouvez choisir de cliquer comme vous ne voulez pas que cela se produise - vous ne voulez gérer que les éléments sélectionnés.

En outre, je soupçonne (bien que je n’aie aucune preuve en ce sens) qu’il existe une légère efficacité en utilisant le "clic" sur "en direct".

Lee

1
Lee Atkinson

D'après ce que j'ai compris, la différence principale est que live () garde un œil ouvert sur les nouveaux éléments DOM qui correspondent au sélecteur sur lequel vous travaillez, alors que click () (ou bind ('clic')) attache le hook d'événement et est terminé.

Étant donné que beaucoup de votre code est chargé de manière asynchrone, utiliser live () vous facilitera grandement la vie. Si vous ne connaissez pas exactement le code que vous chargez mais que vous savez quel type d’élément vous allez écouter, l’utilisation de cette fonction est parfaitement logique.

En termes de gains de performances, une alternative à live () serait d’implémenter une fonction de rappel AJAX pour relier les points d’accès aux événements.

var ajaxCallback = function(){
 $('*').unbind('click');
 $('.something').bind('click', someFunction);
 $('.somethingElse').bind('click', someOtherFunction);
}

Vous devrez garder une trace de vos hooks d’événements et vous assurer que cette fonction permet de relier les événements appropriés.

p.s. Les méthodes Ajax .get (), .post (), .load () et .ajax () permettent toutes de spécifier une fonction de rappel.

1
Joe Green

rappelez-vous que l'utilisation de "live" est pour "jQuery 1.3" ou supérieur

dans la version "jQuery 1.4.3" ou supérieure est utilisé "délégué"

et la version "jQuery 1.7 +" ou supérieure est utilisée "on"

$( selector ).live( events, data, handler ); // jQuery 1.3+
$( document ).delegate( selector, events, data, handler ); // jQuery 1.4.3+
$( document ).on( events, selector, data, handler ); // jQuery 1.7+

Depuis jQuery 1.7, la méthode .live () est obsolète.

check http://api.jquery.com/live/

Cordialement, .__ Fernando

0
Fernando

Si vous avez besoin de simplifier le code, le live est généralement préférable dans la plupart des cas ... Si vous souhaitez obtenir les meilleures performances, déléguez toujours mieux que le live. lier (cliquer) vs délégué n'est pas une question aussi simple (si vous avez beaucoup d'éléments similaires, alors déléguer sera meilleur).

0
oryol

En plus de T.J. Crowders répond , j'ai ajouté quelques gestionnaires supplémentaires, notamment le plus récent gestionnaire .on(...) à l'extrait de code afin que vous puissiez voir quels événements sont masqués et ceux qui ne le sont pas.

Ce que j’ai également constaté, c’est que .live() est non seulement déconseillé, mais a été supprimé depuis jQuery 1.9.x. Mais les autres, c'est-à-dire 
.click, .delegate/.undelegate et .on/.off 
Sont toujours là.

Notez également qu'il y a plus de discussion à ce sujet ici sur Stackoverflow .

Si vous devez corriger le code hérité qui s'appuie sur .live, mais que vous devez utiliser une nouvelle version de jQuery (> 1.8.3), vous pouvez le réparer avec cet extrait:

// fix if legacy code uses .live, but you want to user newer jQuery library
if (!$.fn.live) {
    // in this case .live does not exist, emulate .live by calling .on
    $.fn.live = function(events, handler) {
      $(this).on(events, null, {}, handler);
    };
}

Le but de l'extrait ci-dessous, qui est une extension du script de T.J., est que vous pouvez essayer par vous-même instantanément ce qui se passe si vous liez plusieurs gestionnaires - alors s'il vous plaît lancez l'extrait et cliquez sur les textes ci-dessous:

jQuery(function($) {

  // .live connects function with all spans
  $('span').live('click', function() {
    display("<tt>live</tt> caught a click!");
  });

  // --- catcher1 events ---

  // .click connects function with id='catcher1'
  $('#catcher1').click(function() {
    display("Click Catcher1 caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  // --- catcher2 events ---

  // .click connects function with id='catcher2'
  $('#catcher2').click(function() {
    display("Click Catcher2 caught a click and prevented <tt>live</tt>, <tt>delegate</tt> and <tt>on</tt> from seeing it.");
    return false;
  });

  // .delegate connects function with id='catcher2'
  $(document).delegate('#catcher2', 'click', function() {
    display("Delegate Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  // .on connects function with id='catcher2'
  $(document).on('click', '#catcher2', {}, function() {
    display("On Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  // --- catcher3 events ---

  // .delegate connects function with id='catcher3'
  $(document).delegate('#catcher3', 'click', function() {
    display("Delegate Catcher3 caught a click and <tt>live</tt> and <tt>on</tt> can see it.");
    return false;
  });

  // .on connects function with id='catcher3'
  $(document).on('click', '#catcher3', {}, function() {
    display("On Catcher3 caught a click and and <tt>live</tt> and <tt>delegate</tt> can see it.");
    return false;
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});
<!-- with JQuery 1.8.3 it still works, but .live was removed since 1.9.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>

<style>
span.frame {
    line-height: 170%; border-style: groove;
}
</style>

<div>
  <span class="frame">Click me</span>
  <span class="frame">or me</span>
  <span class="frame">or me</span>
  <div>
    <span class="frame">I'm two levels in</span>
    <span class="frame">so am I</span>
  </div>
  <div id='catcher1'>
    <span class="frame">#1 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span class="frame">me too</span>
  </div>
  <div id='catcher2'>
    <span class="frame">#2 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span class="frame">me too</span>
  </div>
  <div id='catcher3'>
    <span class="frame">#3 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span class="frame">me too</span>
  </div>
</div>

0
Matt