Estoy tratando de entender este particular, la diferencia entre el directa y delegada controladores de eventos mediante la jQuery .en() método. En concreto, la última frase de este párrafo:

Cuando un selector, el controlador de eventos se conoce como delegada. El controlador no se llama cuando se produce el evento directamente en los elementos enlazados, pero sólo para los descendientes (elementos internos) que coincidan con el selector. jQuery burbujas en el evento de la diana hasta el elemento donde el controlador está conectado (es decir, más interna a la más externa elemento) y se ejecuta el controlador de alguno de los elementos a lo largo de esa ruta coincidente con el selector.

¿Qué significa «se ejecuta el controlador de alguno de los elementos»? He hecho una página de prueba a experimentar con el concepto. Pero ambos siguientes construcciones de plomo para el mismo comportamiento:

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

o,

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

Tal vez alguien podría hacer referencia a un ejemplo diferente para aclarar este punto? Gracias.

  • Para todos los interesados: jsperf.com/jquery-fn-on-delegate-vs-direct
  • Me comentó en su violín a continuación, pero aquí, esencialmente no está configurado correctamente (que son vinculantes para el elemento primario, y la delegación está pensada para los niños). Para responder a su pregunta moey significa que el delegado de controlador de partido recién agregado de elementos, donde el uno sin delegación no. La delegación tiene la ventaja de que hay menos eventos enganchado en el navegador que causa una menor consumo de memoria de la aplicación, sin embargo la desventaja es que aumenta el tiempo de proceso de un clic (mínimamente). Si vas a hacer un juego no delegado.
  • La «página de prueba» de que la referencia no está funcionando.
InformationsquelleAutor moey | 2011-11-13

5 Comentarios

  1. 364

    Caso 1 (directo):

    $("div#target span.green").on("click", function() {...});

    == Hey! Quiero que cada lapso.verde dentro de div#destino de escuchar con atención: cuando se hace clic en, haga X.

    Caso 2 (delegado):

    $("div#target").on("click", "span.green", function() {...});

    == Hey, div#destino! Cuando alguno de sus elementos secundarios que son «span.verde» conseguir hacer clic, hacer X con ellos.

    En otras palabras…

    En el caso 1, en cada uno de los abarca, ha sido individualmente instrucciones dadas. Si de nuevo se extiende por crearse, que no han escuchado la instrucción y no responde a los clics. Cada tramo es directamente responsable para sus propios eventos.

    En el caso 2, sólo el contenedor se ha dado la instrucción; es responsable por darse cuenta de clics en nombre de sus elementos secundarios. El trabajo de captura de eventos ha sido delegada. Esto también significa que la instrucción será llevado a cabo por elementos secundarios que se creó en el futuro.

    • Que es una gran explicación, y ha traído claridad a un tema que durante mucho tiempo he negado a entender. Gracias!
    • Entonces, ¿por qué on() permitir que los dos argumentos de que iba a ser casi lo mismo que usar click()?
    • .en() es un propósito general de la API que puede manejar cualquier tipo de evento, incluyendo varios eventos diferentes (se puede poner varios nombres de evento en que la primera cadena.) .haga clic en() es solo un atajo para que la primera forma.
    • Además, para añadir a la idea de la delegación. Dicen que en el futuro, usted tiene más elementos llamados «span.verde» que se agregan a #destino, aquellos útil.verde también se activará la función.
    • Tengo una pregunta acerca de esto. Cómo iba yo a saber que span.green se haga clic en este camino?
    • la devolución de llamada puede tomar un argumento de eventos, y el evento tiene un .objetivo: $(«div#destino»).en(«click», «span.verde», function(evento) { // hacer algo con el evento.target });
    • Yo a ver, Una pregunta más. ¿Y si hay un montón de span.green entonces uno se hace clic. ¿Cómo puedo hacer algo de como esta condición: if( not the clicked element ){ // do something } nota: todos ellos tienen una misma clase.
    • Puede reformular la pregunta?
    • lo siento si su confuso. Teniendo en cuenta este $("div#target").on("click", "span.green", function() {...});, digamos que span.green que se hace referencia en 3 elementos span en div#target y el que ha hecho clic, es el segundo elemento. ¿Cómo puedo hacer que el otro lapso de excluyendo el intervalo (2ª span) que ha sido pulsado para hacer algo.
    • Oh, ya veo. Eso es casi una cuestión separada, pero podría hacerlo: $("div#target span.green").not(event.target).whatever()
    • Veo, así que hay un .not() función. Gracias por tu ayuda.
    • será el objetivo inicial del evento click (puede ser un nodo hijo si span.green tiene hijos). Desde el interior del controlador, debe utilizar el this de referencia. Consulte este violín.
    • Otra nota para agregar al tema de la delegación – es a la vez muy útil y muy eficaz. Vamos a usar menos el navegador de recursos con la delegación vs asociar un evento a cada elemento coincidente. Pensé que mencionar, sólo en el caso de personas que necesitan más razones para el uso de la delegación.
    • ¿qué acerca de las actuaciones? Es el padre de DOM en profundidad buscado cada vez que se hace clic en él?
    • jQuery utiliza «la propagación de los eventos» (ver quirksmode.org/js/events_order.html para obtener más detalles), por lo que los controladores son realmente activa niño-en primer lugar. Así, en un sentido, la delegada controladores de causar más trabajo ya que la búsqueda debe ir todo lo que paso hasta el árbol para encontrar el controlador. Sin embargo: que en realidad es un muy rápido manejo, incluso con un profundo DOM, y el ahorro que se logra en cuanto a no tener que crear y enlazar los nuevos controladores cuando el DOM cambios outweight la diferencia.
    • por favor haga un libro de contestar preguntas a través de todos los temas como este. Para aquellos que están aprendiendo, este tipo de analogía es fantástico. Aplaudo esta respuesta y no se puede agradecer lo suficiente!
    • Si usted lee la siguiente sintaxis en api.jquery.com/on y el significado de cada parámetro, usted va a encontrar una respuesta a su pregunta: .en( eventos [, selector ] [, datos ], controlador ). Como se puede ver, el primer parámetro es «eventos» y la explicación oficial dice que es de tipo String y se añade a esta definición: «Uno o más separada por espacios de los tipos de evento y opcional espacios de nombres, tales como «clic» o «keydown.myPlugin».’ Como N3dst4 dijo en su comentario, «.en() es un propósito general de la API que puede manejar cualquier tipo de evento.» El primer parámetro puede ser, por ejemplo: «haga clic en enviar».

  2. 5

    La primera forma, $("div#target span.green").on(), se une un controlador de clic directamente en el período(s) que coincidan con el selector en el momento en que se ejecuta el código. Esto significa que si otro se extiende se añadió más tarde (o tienen su clase cambiado para que coincida) que se han perdido y no se dispone de un controlador de clic. También significa que si después de quitar el «verde» de la clase de uno de los tramos su haga clic en el controlador continuará la ejecución de jQuery no seguir la pista de cómo el controlador fue asignado y compruebe si el selector todavía los partidos.

    De la segunda manera, $("div#target").on(), se une un controlador haga clic en el div(s) que coincide (de nuevo, esto es en contra de aquellos que coinciden en ese momento), pero cuando un clic se produce en algún lugar en el div de la función de controlador sólo se ejecuta si el clic se produjeron no sólo en el div, pero en un niño elemento coincidente con el selector en el segundo parámetro a .on(), «span.verde». Se hace de esta manera no importa cuando los niño abarca fueron creados, al hacer clic sobre ellos se podrá ejecutar el controlador.

    Así que para una página que no se dinámicamente agregando o cambiando su contenido no notarás diferencia entre los dos métodos. Si usted está dinámicamente la adición de elementos secundarios de la segunda sintaxis significa que usted no tiene que preocuparse acerca de la asignación haga clic en controladores de ellos, porque ya has hecho una vez en el padre.

  3. 4

    La explicación de N3dst4 es perfecto. Basados en esto, podemos asumir que todos los elementos secundarios están dentro del cuerpo, por lo tanto debemos utilizar solo este:

    $('body').on('click', '.element', function(){
        alert('It works!')
    });

    Funciona con directo o delegado evento.

    • jquery aconseja en contra de la utilización del cuerpo, como es más lento, ya que el script tendría que buscar todos los niños dentro del cuerpo, que debe ser mucho en la mayoría de los casos. Es mejor (más rápido) para utilizar la inmediata contenedor principal del elemento.
    • Jquery eliminado método directo que estaba haciendo de la misma como lo mostró. Este desempeño está débil y no debe ser utilizado.
    • En los navegadores modernos, $('body').on() delegación de .element debe comportarse exactamente de la misma como nativo document.body.addEventHandler() con un if (Event.target.className.matches(/\belement\b/)) en la devolución de llamada. Puede ser muy ligeramente más lento en jquery debido a $.proxy sobrecarga, pero no me fijé en eso.
  4. 2

    Tangencial a la OP, pero el concepto que me ayudó a desenredar la confusión con esta característica es que de la envolvente de los elementos han de ser los padres de los elementos seleccionados.

    • Obligado se refiere a lo que está a la izquierda de la .on.
    • Seleccionado se refiere a la 2ª argumento de .on().

    Delegación no funciona así .find(), la selección de un subconjunto de la envolvente de los elementos. El selector sólo se aplica a los estrictos elementos secundarios.

    $("span.green").on("click", ...

    es muy diferente de

    $("span").on("click", ".green", ...

    En particular, para obtener las ventajas @N3dst4 insinúa con «elementos que se crean en el futuro» los elementos enlazados debe ser un permanente de los padres. A continuación, los niños seleccionados que vienen y se van.

    EDITAR

    Lista de por qué delegada .on no funciona

    Difícil razones por las que $('.bound').on('event', '.selected', some_function) puede no funcionar:

    1. Elementos enlazados no es permanente. Fue creado después de llamar a .on()
    2. Elemento seleccionado no es un buen niño de elementos enlazados. Es el mismo elemento.
    3. Elemento seleccionado impedido burbujeante de un evento para los elementos enlazados llamando .stopPropagation().

    (Omitiendo menos complicado razones, tales como un mal escrita selector.)

  5. 1

    Me wro te un post con una comparación directa de los eventos y delegados. Puedo comparar puro js, pero tiene el mismo significado para jquery que sólo encapsular.

    Conclusión es que delegan la gestión de eventos es para la dinámica de la DOM de la estructura donde se unen los elementos pueden ser creados, mientras que el usuario interactúe con la página ( no es necesario de nuevo los enlaces ), y dirigir la gestión de eventos es para la estática de elementos del DOM, cuando sabemos que la estructura no va a cambiar.

    Para más información y comparación –
    http://maciejsikora.com/standard-events-vs-event-delegation/

    Utilizando siempre delegada controladores, que veo que es el actual, muy de moda no es el camino correcto, muchos programadores usan porque «debe ser», pero la verdad es que en directo los controladores de eventos son mejores para algunos la situación y la elección del método que se utilice debe ser apoyado por el conocimiento de las diferencias.

    • si adjuntando muchos manejadores de eventos (por ejemplo, cada fila de una tabla), que es a menudo un mejor rendimiento sabia usar un solo delegado controlador de contenedor en lugar de colocar muchas directa de los controladores. Usted puede ver esto desde el hecho básico de que el controlador de eventos de conteo es de por sí un perfil métrica.

Dejar respuesta

Please enter your comment!
Please enter your name here