2012-09-12 13 views
6

Para aplicaciones web ajax que tienen muchas pantallas y navegaciones, para adjuntar manejadores de eventos para div o enlaces o botones, podemos codificar :jQuery registra automáticamente controlador (es) de eventos a acciones del usuario en elementos que se agregan a DOM por respuesta Ajax

//Using $.on inside Ajax success handler 

$("#container").on("click", "#selector", function(event){ 

}); 
  • este enfoque no funcionará si contenedor no existe en el DOM. Para hacerlo funcionar, tendrá que usar documento o cuerpo como contenedor, el rendimiento puede no ser bueno.

  • Puede haber muchas líneas de código en el controlador de éxito Ajax. Para organizar mejor, puede mover el código a una función y llamar a esa función en el controlador de éxito Ajax. Pero tenemos que hacer muchas funciones de eventos de registro para todas las permutaciones y combinaciones.

  • Funciones de registro de desorden de códigos.

  • Si el controlador de eventos ya estaba registrado, el registro nuevamente causará dos controladores pares. Entonces, tenemos que cancelar el registro y registrar (O adjuntar solo si ya no está adjunto) - No estoy seguro sobre el problema de rendimiento.

¿Alguna otra alternativa?

Pienso en lo siguiente:

  • Mantener un mapa de contenedor, de destino y haga clic en controlador de eventos en un solo lugar para un módulo.
  • En el controlador de eventos globales ajaxComplete, si xhr.responseHTML tiene el contenedor, adjunte el controlador de eventos a los elementos de destino (adjunte solo si ya no está adjunto).

    $(document).ajaxComplete(function(e, xhr, settings){ 
        for(ind in clickEventListeners){eventlistner = clickEventListeners[ind]; 
        if($(eventlistner.container,xhr.responseHTML).length > 0){ 
         $(eventlistner.target).on("click",function(){ 
         eventlistner.processor(this); 
         }); 
        } 
    } 
    }); 
    

Pros: Todos los controladores de eventos documentados en un lugar por un módulo. Sin código desordenado para cada controlador de éxito de Ajax.

Contras: No estoy seguro si alguno.

Por favor, avise si hay alguna sugerencia.

Respuesta

7

Actualizado

Encuadernación un evento a un elemento que se añadirá dinámicamente requiere colocar el oyente en el documento, no el elemento partir de la versión 1.9+. Desde la API de Jquerys, puede encontrar esta línea:

"Los manejadores de eventos están vinculados solo a los elementos seleccionados actualmente; deben existir en la página en el momento en que su código realiza la llamada a .on()."

Por lo tanto, vincular el evento al documento y colocar el selector posteriormente permitirá que este oyente sea realmente reconocido.

$(document).delegate("#selector", "click", 

o

$(document).on("click", "#selector", 

Ejemplo: http://jsfiddle.net/2HA7d/

En Jquery revisiones anteriores de la función en vivo() podría haber sido utilizado que en realidad coloca al oyente al documento que permite que esto funcione exactamente como usted pensaría:

$("#selector").live("click", 

Ejemplo: http://jsfiddle.net/q3jYB/

El segundo ejemplo funciona igual que en el primer ejemplo.

Como el elemento aún no existe, javascript no puede agregar un detector de eventos para el elemento que está buscando. Por lo tanto, cuando intente agregar un oyente para los elementos añadidos dinámicamente y esté usando una versión más nueva de jquery (1.9+) y use on() o delegue(), agregue su detector de eventos al documento como se ve en el primer Fiddle proporcionado.

Editar:

como Will I Am dicho en los comentarios, añadiendo el detector de eventos al contenedor si es posible es también una opción muy viable y puede mejorar el rendimiento

Fuentes:

https://api.jquery.com/on/

http://jquery.com/upgrade-guide/1.9/

How does jQuery .live() work?

Espero que esto ayude.

+1

Respuesta actualizada para proporcionar más de una explicación – Jesse

+0

Gran respuesta y buenos enlaces de referencia. +1 –

+1

$ ("# contenedor"). Delegado ("#selector", "clic" ... Debería mejorar el rendimiento. Como pocos eventos aparecerán hasta #container y se tendrán que realizar menos comprobaciones. –

-1

Enlazar un controlador de eventos a document o body puede no ser una buena idea si ya está presente en DOM.

Pero si los elementos se generan de forma dinámica (como en su caso), entonces es posible enlazar un evento para documentar a continuación, el mantenimiento de su propia pila de contenedores, destino y haga clic controlador de eventos, como:

$(document).on("click", "#selector", function() {}) 

Fuente : Are there any drawbacks to listen events on document level in jQuery?

1

Estaba en una situación similar a la tuya, prueba esto, ¡esto funciona muy bien en mi parte!

  • En primer lugar en el archivo principal Ato controlador de eventos como éste:

    $('body').bind('gridloaded', function(e,f) { my logic });

  • En archivos ajax que están poblando dinámicamente mi árbol DOM al final agrego gatillo cuando sea necesario y el elemento de identificación I 'm en adelante, como esto:

    $('body').trigger('gridloaded', $(this).attr('id'));

    onClickButton: function(){ $("body").trigger("gridloaded", $(this).attr('id')) }

Me encanta este enfoque porque está limpio: no importa cuánto tiempo tome la llamada ajax, siempre activará solo un evento en el momento adecuado.

Cuestiones relacionadas