Directa vs Delegado - jQuery.en()


Estoy tratando de entender esta diferencia particular entre los controladores de eventos direct y delegated usando el jQuery .on () método. Concretamente, la última frase de este párrafo:

Cuando se proporciona un selector, el controlador de eventos se denomina delegado. El controlador no se llama cuando el evento ocurre directamente en el elemento enlazado, sino solo para los descendientes (elementos internos) que coinciden con el selector. jQuery en español el evento desde el evento de destino hasta el elemento donde está conectado el controlador (es decir, el elemento más interno al más externo) y ejecuta el controlador para cualquier elemento a lo largo de esa ruta que coincida con el selector.

¿Qué significa "ejecuta el controlador para cualquier elemento"? Hice una página de prueba para experimentar con el concepto. Pero ambos constructos siguientes conducen al 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 referirse a un ejemplo diferente para aclarar en este punto? Gracias.

Author: RPichioli, 2011-11-13

5 answers

Caso 1 (directo):

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

== Hey! Quiero cada palmo.verde dentro de div # target para escuchar: cuando se hace clic en, hacer X.

Caso 2 (delegado):

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

== Hey, div # target! Cuando cualquiera de sus elementos hijo que son " span.verde " haz clic, haz X con ellos.

En otras palabras...

En el caso 1, a cada uno de esos tramos se le han dado instrucciones individualmente. Si se crean nuevos tramos, no habrán escuchado la instrucción y no responde a los clics. Cada span es directamente responsable de sus propios eventos.

En el caso 2, solo se ha dado la instrucción al contenedor; es responsable de notar clics en nombre de sus elementos secundarios. El trabajo de captura de eventos ha sido delegado. Esto también significa que la instrucción se llevará a cabo para los elementos secundarios que se creen en el futuro.

 345
Author: N3dst4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-30 09:37:58

La primera forma, $("div#target span.green").on(), enlaza un manejador de clics directamente a los span(s) que coinciden con el selector en el momento en que se ejecuta el código. Esto significa que si otros spans se agregan más tarde (o se cambia su clase para que coincida), se han perdido y no tendrán un controlador de clics. También significa que si luego elimina la clase" verde " de uno de los tramos, su controlador de clics continuará ejecutándose-jQuery no realiza un seguimiento de cómo se asignó el controlador y comprueba si el selector sigue coincidir.

La segunda forma, $("div#target").on(), enlaza un manejador de clics con los div(s) que coinciden (de nuevo, esto es contra los que coinciden en ese momento), pero cuando se produce un clic en algún lugar del div, la función del manejador solo se ejecutará si el clic se produjo no solo en el div sino en un elemento secundario que coincida con el selector en el segundo parámetro a .on(), "span.verde". Hecho de esta manera, no importa cuándo se crearon esos tramos secundarios, al hacer clic sobre ellos se ejecutará el controlador.

So para una página que no está agregando o cambiando dinámicamente su contenido, no notará una diferencia entre los dos métodos. Si está agregando dinámicamente elementos secundarios adicionales, la segunda sintaxis significa que no tiene que preocuparse por asignarles controladores de clics porque ya lo ha hecho una vez en el padre.

 5
Author: nnnnnn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-13 11:03:55

La explicación de N3dst4 es perfecta. Basándonos en esto, podemos asumir que todos los elementos hijos están dentro del cuerpo, por lo tanto necesitamos usar solo esto:

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

Funciona con evento directo o delegado.

 4
Author: Brynner Ferreira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-25 16:42:17

Tangencial al OP, pero el concepto que me ayudó a desentrañar la confusión con esta característica es quelos elementos enlazados deben ser padres de los elementos seleccionados .

  • Encuadernado se refiere a lo que queda de la .on.
  • Selected se refiere al segundo argumento de .on().

La delegación no funciona como .find(), seleccionando un subconjunto de los elementos enlazados. El selector solo se aplica a elementos secundarios estrictos.

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

Es muy diferente de

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

En particular, para obtener las ventajas que @N3dst4 sugiere con "elementos que se crean en el futuro", el elemento enlazado debe ser un padre permanente. Entonces los niños seleccionados pueden ir y venir.

EDITAR

Lista de verificación de por qué delegada .on no funciona

Razones difíciles por las que $('.bound').on('event', '.selected', some_function) puede no funcionar:

  1. El elemento enlazado no es permanente. Fue creado después de llamar .on()
  2. El elemento seleccionado no es un hijo de un elemento enlazado. Es el mismo elemento.
  3. El elemento seleccionado impidió burbujear de un evento al elemento enlazado llamando a .stopPropagation().

(Omitiendo razones menos complicadas, como un selector mal escrito.)

 2
Author: Bob Stein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-21 11:48:06

I wro te a post with a comparison of direct events and delegated. Comparo js puro pero tiene el mismo significado para jquery que solo lo encapsula.

La conclusión es que el manejo de eventos delegados es para la estructura DOM dinámica donde los elementos enlazados se pueden crear mientras el usuario interactúa con la página ( no hay necesidad de enlaces de nuevo ), y el manejo directo de eventos es para los elementos DOM estáticos, cuando sabemos que la estructura no cambiará.

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

Usar manejadores siempre delegados, que veo que está muy de moda, no es la manera correcta, muchos programadores lo usan porque "debería usarse", pero la verdad es que los manejadores de eventos directos son mejores para alguna situación y la elección de qué método debe ser apoyado por el conocimiento de las diferencias.

 1
Author: Maciej Sikora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-13 10:21:09