change all javascript jquery jquery-selectors jquery-on

javascript - all - ¿Deberían todos los eventos de jquery vincularse a $(documento)?



jquery select events (2)

La delegación de eventos es una técnica para escribir sus manejadores antes de que el elemento realmente exista en DOM. Este método tiene sus propias desventajas y debe usarse solo si tiene tales requisitos.

¿Cuándo debería usar la delegación de eventos?

  1. Cuando vincula un controlador común para más elementos que necesitan la misma funcionalidad. (Ejemplo: hover de fila de tabla)
    • En el ejemplo, si tuviera que enlazar todas las filas mediante enlace directo, terminaría creando n controlador para n filas en esa tabla. Al usar el método de delegación, podría terminar manejando todos los que están en 1 manejador simple.
  2. Cuando agrega contenido dinámico con más frecuencia en DOM (por ejemplo: Agregar / eliminar filas de una tabla)

¿Por qué no deberías usar la delegación de eventos?

  1. La delegación de eventos es más lenta en comparación con vincular el evento directamente al elemento.
    • Compara el selector de objetivos en cada burbuja que golpea, la comparación será tan cara como complicada.
  2. Sin control sobre el evento que burbujea hasta que golpea el elemento al que está ligado.

PD: incluso para los contenidos dinámicos, no es necesario utilizar el método de delegación de eventos si se vincula el controlador después de que los contenidos se inserten en DOM. (Si el contenido dinámico se agrega, no se elimina o se vuelve a agregar con frecuencia)

De dónde viene esto

La primera vez que aprendí jQuery, normalmente adjunto eventos como este:

$(''.my-widget a'').click(function() { $(this).toggleClass(''active''); });

Después de aprender más sobre la velocidad del selector y la delegación de eventos, leí en varios lugares que "la delegación de eventos jQuery hará que su código sea más rápido". Entonces comencé a escribir código como este:

$(''.my-widget'').on(''click'',''a'',function() { $(this).toggleClass(''active''); });

Esta también fue la forma recomendada de replicar el comportamiento del evento .live obsoleto. Lo cual es importante para mí, ya que muchos de mis sitios agregan / eliminan dinámicamente widgets todo el tiempo. Lo anterior no se comporta exactamente igual que .live (), ya que solo los elementos agregados al contenedor ya existente ''.my-widget'' obtendrán el comportamiento. Si agrego dinámicamente otro bloque de html después de que se ejecutó ese código, esos elementos no obtendrán los eventos vinculados a ellos. Me gusta esto:

setTimeout(function() { $(''body'').append(''<div class="my-widget"><a>Click does nothing</a></div>''); }, 1000);


Lo que quiero lograr:

  1. el antiguo comportamiento de .live () // que significa unir eventos a elementos aún no existentes
  2. los beneficios de .on ()
  3. el rendimiento más rápido para unir eventos
  4. Manera simple de administrar eventos

Ahora adjunto todos los eventos como este:

$(document).on(''click.my-widget-namespace'', ''.my-widget a'', function() { $(this).toggleClass(''active''); });

Lo cual parece cumplir todos mis objetivos. (Sí, es más lento en IE por alguna razón, ¿por qué?) Es rápido porque solo un evento está vinculado a un elemento singular y el selector secundario solo se evalúa cuando se produce el evento (corrígeme si esto está mal aquí). El espacio de nombres es increíble, ya que facilita el alternar el oyente del evento.

Mi solución / pregunta

Así que estoy empezando a pensar que los eventos de jQuery siempre deben estar vinculados a $ (documento).
¿Hay alguna razón por la cual no quieras hacer esto?
¿Podría esto ser considerado una mejor práctica? Si no, ¿por qué?

Si has leído todo esto, gracias. Agradezco cualquier / todos los comentarios / ideas.

Suposiciones

  1. Usando jQuery que admite .on() // al menos la versión 1.7
  2. Desea que el evento se agregue al contenido agregado dinámicamente

Lecturas / Ejemplos:

  1. http://24ways.org/2011/your-jquery-now-with-less-suck
  2. http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery
  3. http://www.jasonbuckboyer.com/playground/speed/speed.html
  4. http://api.jquery.com/on/

No, NO debe obligar a todos los manejadores de eventos delegados al objeto del document . Ese es probablemente el peor escenario que podrías crear.

En primer lugar, la delegación de eventos no siempre hace que su código sea más rápido. En algunos casos, es ventajoso y en algunos casos no. Debe usar la delegación de eventos cuando realmente necesite delegación de eventos y cuando se beneficie de ellos. De lo contrario, debe vincular los manejadores de eventos directamente a los objetos donde ocurre el evento, ya que generalmente será más eficiente.

En segundo lugar, NO deberías vincular todos los eventos delegados a nivel de documento. Esta es exactamente la razón .live() cual .live() fue desaprobado porque es muy ineficiente cuando tienes muchos eventos atados de esta manera. Para el manejo delegado de eventos, es MUCHO más eficiente vincularlos al padre más cercano que no sea dinámico.

En tercer lugar, no todos los eventos funcionan o todos los problemas se pueden resolver con la delegación. Por ejemplo, si quiere interceptar eventos clave en un control de entrada y bloquear el ingreso de claves no válidas al control de entrada, no puede hacer eso con el manejo delegado de eventos porque para cuando el evento brota hasta el controlador delegado, ya ha pasado procesado por el control de entrada y es demasiado tarde para influir en ese comportamiento.

Aquí hay ocasiones en que se requiere o es ventajosa la delegación de eventos:

  • Cuando los objetos que está capturando eventos se crean / eliminan dinámicamente y aún desea capturar eventos en ellos sin tener que vincular explícitamente los manejadores de eventos cada vez que crea uno nuevo.
  • Cuando tiene muchos objetos que quieren exactamente el mismo controlador de eventos (donde los lotes son al menos cientos). En este caso, puede ser más eficiente en el momento de la instalación vincular un controlador de eventos delegados en lugar de cientos o más controladores de eventos directos. Tenga en cuenta que el manejo delegado de eventos siempre es menos eficiente en tiempo de ejecución que los manejadores de eventos directos.
  • Cuando intenta capturar (en un nivel superior en su documento) los eventos que ocurren en cualquier elemento del documento.
  • Cuando su diseño está utilizando explícitamente eventos de burbujeo y stopPropagation () para resolver algún problema o función en su página.

Para entender esto un poco más, uno necesita entender cómo funcionan los manejadores de eventos delegados de jQuery. Cuando llamas algo como esto:

$("#myParent").on(''click'', ''button.actionButton'', myFn);

Instala un controlador de eventos jQuery genérico en el objeto #myParent . Cuando surge un evento de clic en este controlador de eventos delegados, jQuery tiene que pasar por la lista de controladores de eventos delegados adjuntos a este objeto y ver si el elemento de origen para el evento coincide con cualquiera de los selectores en los controladores de eventos delegados.

Debido a que los selectores pueden estar bastante involucrados, esto significa que jQuery tiene que analizar cada selector y luego compararlo con las características del objetivo del evento original para ver si coincide con cada selector. Esta no es una operación barata. No es gran cosa si solo hay uno de ellos, pero si coloca todos los selectores en el objeto de documento y hay cientos de selectores para comparar con cada evento burbujeante, esto puede comenzar a empeorar el rendimiento del manejo de eventos.

Por esta razón, desea configurar sus manejadores de eventos delegados para que un manejador de eventos delegado esté lo más cerca posible del objeto de destino. Esto significa que habrá menos eventos que burbujearán a través de cada controlador de eventos delegados, mejorando así el rendimiento. Poner todos los eventos delegados en el objeto de documento es el peor rendimiento posible porque todos los eventos borrosos tienen que pasar por todos los controladores de eventos delegados y se evalúan contra todos los posibles selectores de eventos delegados. Esto es exactamente por qué .live() está en desuso porque esto es lo que hizo .live() y resultó ser muy ineficiente.

Por lo tanto, para lograr un rendimiento optimizado:

  1. Solo use el manejo delegado de eventos cuando en realidad proporcione una función que necesite o aumente el rendimiento. No siempre lo use porque es fácil porque en realidad no lo necesita. De hecho, tiene un peor rendimiento en el momento de envío del evento que el enlace de evento directo.
  2. Adjunte los manejadores de eventos delegados al padre más cercano al origen del evento como sea posible. Si está utilizando el manejo delegado de eventos porque tiene elementos dinámicos para los que desea capturar eventos, seleccione el elemento primario más cercano que no sea dinámico.
  3. Use selectores fáciles de evaluar para los manejadores de eventos delegados. Si siguió cómo funciona el manejo de eventos delegados, comprenderá que un controlador de eventos delegado tiene que compararse con muchos objetos muchas veces para elegir un selector tan eficiente como sea posible o agregar clases simples a sus objetos para que se puedan usar selectores más simples. aumentar el rendimiento del manejo delegado de eventos.