¿Cómo vincular eventos en contenido cargado Ajax?

96

Tengo un enlace, myLinkque debería insertar contenido cargado con AJAX en un div(appendedContainer) de mi página HTML. El problema es que el clickevento que he vinculado con jQuery no se está ejecutando en el contenido recién cargado que se inserta en el contenedor adjunto. El clickevento está vinculado a elementos DOM que no están cargados con mi función AJAX.

¿Qué tengo que cambiar para que el evento quede vinculado?

Mi HTML:

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

Mi 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!");});

El contenido a cargar:

<div>some content</div>
<a class="mylink" href="otherurl">Link</a>
confile
fuente
1
Nota: Lo siguiente no funciona. Falta .el selector de clases.
indefinido
¡Esto fue un error tipográfico! Todavía no funciona.
confile
1
Consulte el método jquery .load () . $ ('# destino'). load ('fuente.html');
km6zla
¿Load () hace algo diferente?
confile

Respuestas:

218

Utilice la delegación de eventos para elementos creados dinámicamente:

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

Esto realmente funciona, aquí hay un ejemplo en el que agregué un ancla con la clase en .mylinklugar de data: http://jsfiddle.net/EFjzG/

dsgriffin
fuente
Esto es lo que escribí que hice.
confile
@confile ¿De verdad? He leído su pregunta dos veces y no la veo ni por escrito ni en código.
dsgriffin
@confile .. Vea la respuesta otra vez .. eso es diferente de lo que tiene
Mohammad Adil
2
@confile ¡¡Mi respuesta funciona !! aquí hay un ejemplo de ello: jsfiddle.net/EFjzG
dsgriffin
1
Hola, esta respuesta funciona bien. El evento se adjunta en todo el documento, por lo que básicamente cada clic en la página desencadena un evento, pero luego, el selector '.mylink' se aplica para filtrar los eventos de clic que necesitamos. Excelente tecnica.
Emir
23

Si el contenido se agrega después de llamar a .on (), deberá crear un evento delegado en un elemento principal del contenido cargado. Esto se debe a que los controladores de eventos están vinculados cuando se llama a .on () (es decir, normalmente al cargar la página). Si el elemento no existe cuando se llama .on (), ¡el evento no estará vinculado a él!

Debido a que los eventos se propagan a través del DOM, podemos resolver esto creando un evento delegado en un elemento principal ( .parent-elementen el ejemplo siguiente) que sabemos que existe cuando se carga la página. Así es cómo:

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

Algunas lecturas más sobre el tema:

Kai
fuente
3
Prefiero esta respuesta a la de @lifetimes, porque me dice que configure el controlador en algún elemento principal que está presente en el momento de la carga, no necesariamente hasta el documento . Esto hace que el selector del segundo argumento sea onmenos propenso a coincidencias no deseadas.
R. Schreurs
Si la clase html cargada por ajax también es elemento principal, entonces no está funcionando
jafar pinjar
6

si su pregunta es "cómo vincular eventos en contenido cargado ajax", puede hacer esto:

$("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');
});

por lo que no necesita colocar su configuración en cada código ajax

antoniputra
fuente
2

A partir de jQuery 1.7, el .live()método está obsoleto. Úselo .on()para adjuntar controladores de eventos.

Ejemplo -

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

Para aquellos que todavía están buscando una solución, la mejor manera de hacerlo es vincular el evento en el documento mismo y no vincularlo con el evento "listo". Por ejemplo:

$(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
        }
    });
});

});

Fuente real
fuente
1

Si su respuesta ajax contiene entradas de formulario html, por ejemplo, esto sería genial:

$(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
fuente
0

use jQuery.live () en su lugar. Documentación aquí

p.ej

$("mylink").live("click", function(event) { alert("new link clicked!");});
ROMMEL
fuente
9
.live()está en desuso y se eliminó en la última versión de jquery.
Mohammad Adil
0

Para ASP.NET intente esto:

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

Esto parece funcionar al cargar la página y al cargar el panel de actualización

Encuentre la discusión completa aquí .

Miguel
fuente
2
¿De dónde proviene esta "Aplicación del sistema"? - '
André Marcondes Teixeira
Parece pertenecer a ASP.NET: msdn.microsoft.com/en-us/library/vstudio/…
Michael