Comment lier des événements sur du contenu chargé Ajax?

96

J'ai un lien myLink,, qui devrait insérer du contenu chargé AJAX dans un div(appendedContainer) de ma page HTML. Le problème est que l' clickévénement que j'ai lié avec jQuery n'est pas exécuté sur le contenu nouvellement chargé qui est inséré dans le appendedContainer. L' clickévénement est lié aux éléments DOM qui ne sont pas chargés avec ma fonction AJAX.

Que dois-je changer pour que l'événement soit lié?

Mon HTML:

<a class="LoadFromAjax" href="someurl">Load Ajax</a>
<div class="appendedContainer"></div>

Mon JavaScript:

$(".LoadFromAjax").on("click", function(event) {
    event.preventDefault();
    var url = $(this).attr("href"),
        appendedContainer = $(".appendedContainer");

    $.ajax({
    url: url,
    type : 'get',
    complete : function( qXHR, textStatus ) {           
        if (textStatus === 'success') {
            var data = qXHR.responseText
            appendedContainer.hide();
            appendedContainer.append(data);
            appendedContainer.fadeIn();
        }
      }
    });

});

$(".mylink").on("click", function(event) { alert("new link clicked!");});

Le contenu à charger:

<div>some content</div>
<a class="mylink" href="otherurl">Link</a>
confiler
la source
1
Remarque: ce qui suit ne fonctionne pas. Vous manquez .pour le sélecteur de classe.
undefined
C'était une faute de frappe! Cela ne fonctionne toujours pas.
confilez
1
Voir la méthode jquery .load () . $ ('# cible'). load ('source.html');
km6zla
Load () fait-il quelque chose de différent?
confile

Réponses:

218

Utilisez la délégation d'événements pour les éléments créés dynamiquement:

$(document).on("click", '.mylink', function(event) { 
    alert("new link clicked!");
});

Cela fonctionne réellement, voici un exemple où j'ai ajouté une ancre avec la classe .mylinkau lieu de data- http://jsfiddle.net/EFjzG/

dsgriffin
la source
C'est ce que j'ai écrit que j'ai fait.
confile
@confile Vraiment? J'ai lu votre question deux fois et je ne la vois ni par écrit ni par code?
dsgriffin
@confile .. Voir la réponse agian .. c'est différent de ce que vous avez
Mohammad Adil
2
@confile Ma réponse fonctionne !! en voici un exemple - jsfiddle.net/EFjzG
dsgriffin
1
Salut, cette réponse fonctionne très bien. L'événement est attaché à l'ensemble du document, donc fondamentalement chaque clic sur la page déclenche un événement, mais ensuite, le sélecteur '.mylink' est appliqué pour filtrer les événements de clic dont nous avons besoin. Excellente technique.
Emir
23

Si le contenu est ajouté après l'appel de .on (), vous devrez créer un événement délégué sur un élément parent du contenu chargé. C'est parce que les gestionnaires d'événements sont liés lorsque .on () est appelé (c'est-à-dire généralement lors du chargement de la page). Si l'élément n'existe pas lorsque .on () est appelé, l'événement ne lui sera pas lié!

Étant donné que les événements se propagent via le DOM, nous pouvons résoudre ce problème en créant un événement délégué sur un élément parent ( .parent-elementdans l'exemple ci-dessous) dont nous savons qu'il existe lorsque la page se charge. Voici comment:

$('.parent-element').on('click', '.mylink', function(){
  alert ("new link clicked!");
})

Quelques lectures supplémentaires sur le sujet:

Kai
la source
3
Je préfère cette réponse à celle de @lifetimes, car elle me dit de définir le gestionnaire sur un élément parent présent au moment du chargement, pas nécessairement jusqu'au document . Cela rend le sélecteur du deuxième argument onmoins sujet aux correspondances involontaires.
R. Schreurs
Si la classe html chargée ajax a également l'élément parent, cela ne fonctionne pas
jafar pinjar
6

si votre question est "comment lier des événements sur du contenu chargé ajax", vous pouvez faire comme ceci:

$("img.lazy").lazyload({
    effect : "fadeIn",
    event: "scrollstop",
    skip_invisible : true
}).removeClass('lazy');

// lazy load to DOMNodeInserted event
$(document).bind('DOMNodeInserted', function(e) {
    $("img.lazy").lazyload({
        effect : "fadeIn",
        event: "scrollstop",
        skip_invisible : true
    }).removeClass('lazy');
});

vous n'avez donc pas besoin de placer votre configuration sur chaque code ajax

Antoniputra
la source
2

Depuis jQuery 1.7, la .live()méthode est obsolète. Utilisez .on()pour attacher des gestionnaires d'événements.

Exemple -

$( document ).on( events, selector, data, handler );
Elnaz
la source
1

Pour ceux qui recherchent encore une solution, la meilleure façon de le faire est de lier l'événement sur le document lui-même et de ne pas lier avec l'événement "prêt à l'emploi". Par exemple:

$(function ajaxform_reload() {
$(document).on("submit", ".ajax_forms", function (e) {
    e.preventDefault();
    var url = $(this).attr('action');
    $.ajax({
        type: 'post',
        url: url,
        data: $(this).serialize(),
        success: function (data) {
            // DO WHAT YOU WANT WITH THE RESPONSE
        }
    });
});

});

Source réelle
la source
1

Si votre réponse ajax contient des entrées de formulaire html par exemple, ce serait génial:

$(document).on("change", 'input[type=radio][name=fieldLoadedFromAjax]', function(event) { 
if (this.value == 'Yes') {
  // do something here
} else if (this.value == 'No') {
  // do something else here.
} else {
   console.log('The new input field from an ajax response has this value: '+ this.value);
}

});
ChristianG
la source
0

utilisez plutôt jQuery.live (). Documentation ici

par exemple

$("mylink").live("click", function(event) { alert("new link clicked!");});
ROMMEL
la source
9
.live()est obsolète et supprimée dans la dernière version de jquery.
Mohammad Adil
0

Pour ASP.NET, essayez ceci:

<script type="text/javascript">
    Sys.Application.add_load(function() { ... });
</script>

Cela semble fonctionner au chargement de la page et au chargement du panneau de mise à jour

Veuillez trouver la discussion complète ici .

Michael
la source
2
D'où vient ce "Sys.Application"? - '
André Marcondes Teixeira
Il semble appartenir à ASP.NET: msdn.microsoft.com/en-us/library/vstudio/…
Michael