web-dev-qa-db-fra.com

Méthode jQuery .live () vs .on () pour ajouter un événement click après le chargement du code HTML dynamique

J'utilise jQuery v.1.7.1 où la méthode .live () est apparemment obsolète.

Le problème que je rencontre est que lors du chargement dynamique de HTML dans un élément en utilisant:

$('#parent').load("http://..."); 

Si j'essaie d'ajouter un événement click par la suite, il n'enregistre pas l'événement à l'aide de l'une des méthodes suivantes:

$('#parent').click(function() ...); 

ou

// according to documentation this should be used instead of .live()
$('#child').on('click', function() ...); 

Quelle est la bonne façon de réaliser cette fonctionnalité? Cela semble fonctionner uniquement avec .live () pour moi, mais je ne devrais pas utiliser cette méthode. Notez que #child est un élément chargé dynamiquement.

Merci.

206
Sean Thoman

Si vous souhaitez que le gestionnaire de clics fonctionne pour un élément chargé dynamiquement, définissez-le sur un objet parent (non chargé de manière dynamique) et attribuez-lui un sélecteur qui correspond à votre objet dynamique, comme suit:

$('#parent').on("click", "#child", function() {});

Le gestionnaire d'événement sera attaché à l'objet #parent et à chaque fois qu'un événement de clic se déclarant sur lui proviendrait de #child, il déclenchera votre gestionnaire de clics. C'est ce qu'on appelle la gestion d'événements déléguée (la gestion d'événements est déléguée à un objet parent).

C’est ainsi que vous pouvez attacher l’événement à l’objet #parent même lorsque l’objet #child n’existe pas encore, mais que lorsqu’il existera plus tard et que vous aurez cliqué dessus, l’événement de clic se propagera au #parent objet, il verra qu'il est originaire de #child et il existe un gestionnaire d'événements permettant de cliquer sur #child et de déclencher votre événement.

589
jfriend00

Essaye ça:

$('#parent').on('click', '#child', function() {
    // Code
});

De la $.on() documentation:

Les gestionnaires d'événements ne sont liés qu'aux éléments actuellement sélectionnés; ils doivent exister sur la page au moment où votre code appelle l'appel à .on().

Votre élément #child n'existe pas lorsque vous appelez $.on(), ainsi l'événement n'est pas lié (contrairement à $.live()). #parent, cependant, existe , il est donc correct d'associer l'événement à cet événement.

Le deuxième argument de mon code ci-dessus agit en tant que "filtre" pour ne se déclencher que si l'événement bouillonne jusqu'à #parent à partir de #child.

32
Bojangles

$(document).on('click', '#selector', function() { /* do stuff */ });

EDIT: Je fournis un peu plus d'informations sur la façon dont cela fonctionne, parce que ... mots. Avec cet exemple, vous placez un écouteur sur l'ensemble du document.

Lorsque vous click sur un ou plusieurs éléments correspondant à #selector, l'événement passe dans le document principal - tant qu'aucun autre écouteur n'a appelé la méthode event.stopPropagation() - ce qui dépasserait le bouillonnement d'un événement à des éléments parents.

Au lieu de vous lier à un élément spécifique ou à un ensemble d'éléments, vous écoutez tous les événements provenant d'éléments correspondant au sélecteur spécifié. Cela signifie que vous pouvez créer un seul programme d'écoute, une fois, qui correspond automatiquement aux éléments existants et à tous les éléments ajoutés dynamiquement.

Ceci est intelligent pour plusieurs raisons, y compris les performances et l'utilisation de la mémoire (dans les applications à grande échelle)

21
L422Y

L'équivalent de .live () dans 1.7 ressemble à ceci:

$(document).on('click', '#child', function() ...); 

Fondamentalement, surveillez le document pour les événements de clic et filtrez-le pour #child.

11
Jared

Je sais qu'il est un peu tard pour une réponse, mais j'ai créé un polyfill pour la méthode .live (). Je l'ai testé dans jQuery 1.11, et cela semble plutôt bien fonctionner. Je sais que nous sommes supposés implémenter la méthode .on () autant que possible, mais dans les grands projets, où il n'est pas possible de convertir tous les appels .live () en appels .on () équivalents pour une raison quelconque, les suivantes travail:

if(jQuery && !jQuery.fn.live) {
    jQuery.fn.live = function(evt, func) {
        $('body').on(evt, this.selector, func);
    }
}

Incluez-le simplement après avoir chargé jQuery et avant d'appeler live ().

9
NSV

.on () est pour jQuery version 1.7 et supérieure. Si vous avez une version plus ancienne, utilisez ceci:

$("#SomeId").live("click",function(){
    //do stuff;
});
5
Matt Cashatt

J'ai utilisé 'live' dans mon projet mais un de mes amis m'a suggéré d'utiliser 'on' au lieu de vivre. Et quand j’ai essayé d’utiliser ça, j’ai rencontré un problème comme celui que vous aviez.

Sur mes pages, je crée des rangées de tableaux de boutons et de nombreux objets de manière dynamique. mais quand j'utilise la magie a disparu.

Les autres solutions, comme l'utiliser comme un enfant, appellent simplement vos fonctions à chaque clic. Mais je trouve un moyen de faire en sorte que cela se reproduise et voici la solution.

Écrivez votre code comme:

function caller(){
    $('.ObjectYouWntToCall').on("click", function() {...magic...});
}

Appeler l'appelant (); après avoir créé votre objet dans la page comme ceci.

$('<dom class="ObjectYouWntToCall">bla... bla...<dom>').appendTo("#whereeveryouwant");
caller();

De cette façon, votre fonction est appelée quand il est supposé ne pas cliquer à chaque clic sur la page.

3
Coderx07