El manejo de eventos es otra de esas grandes razones para usar jQuery. Existen algunas diferencias entre navegadores en cuanto a cómo hacerlo, que jQuery normaliza en una API simple, al tiempo que aplica algunas de las mejores prácticas.
Básicamente, hay un método que necesita saber: .on()
- funciona así:
$("button").on("click", function() ( // do something ));
Aquí le damos al .on()
método solo dos parámetros. El nombre del evento ("clic") y una función que se ejecutará cuando ese evento ocurra en cualquiera de los elementos de esa selección. Lee bastante limpio, ¿no?
Las personas con cierta experiencia previa jQuery podrían estar familiarizados con otros métodos de unión como .bind()
, .live()
o .delegate()
. No se preocupe más por ellos, jQuery moderno los ha combinado todos en lo .on()
que siempre hace la mejor práctica.
Al vincular un evento como hicimos anteriormente, puede (y normalmente es inteligente) incluir un nombre de parámetro en la función. Ese parámetro será "el objeto de evento" dentro de la función:
$("button").on("click", function(event) ( // event => "the event object" ));
A través de ese objeto de evento obtienes mucha información. Ya estás un poco familiarizado con él porque lo usamos para .preventDefault()
y .stopPropagation()
. Pero también hay mucha otra información directa en ese objeto. Cosas como qué tipo de evento fue (en caso de que varios eventos activen esta misma función), cuándo sucedió, dónde sucedió (coordenadas, si corresponde), en qué elemento sucedió y mucho más. Vale la pena inspeccionar el objeto de evento con regularidad al codificar.
Existe un concepto de delegación de eventos que es extremadamente importante al trabajar con eventos. Es una buena práctica moderna muy inteligente. Incorpora la idea de alcance.
Una forma tradicional de pensar en la vinculación de eventos es como "buscar todos los botones en la página y vincularlos con un evento de clic". Eso, por supuesto, funciona, pero es:
- No muy eficiente
- Frágil
No es eficiente porque está forzando inmediatamente a JavaScript a encontrar todos esos elementos de botón cuando, con la delegación, podría estar encontrando un elemento más fácil de encontrar.
Frágil porque si se agregan más botones a la página, ya se han perdido el barco en la encuadernación y deberán volver a encuadernarse.
Con la delegación de eventos, vincularía ese evento de clic a un elemento que esté más arriba en el árbol DOM que los botones que los contienen todos. Podría ser un
lugar, podría ser el document
mismo. Cuando vincula el evento de clic a ese elemento superior, le dice que todavía está interesado en los clics que ocurrieron en los botones. Luego, cuando se hace clic en un botón, debido a la naturaleza de la propagación del evento, ese clic finalmente se activará en el elemento superior. Pero el objeto de evento sabrá si el clic original ocurrió en un botón o no, y la función que ha configurado para activar ese evento se activará o no si conoce esa información.
En este screencast, lo demostramos así:
$("#scope").on("click", "textarea", function(event) ( // Do stuff! console.log(event); ));
Ahora imagina si agregamos otro a eso
. No necesitamos volver a vincular ningún evento, porque el evento todavía está felizmente vinculado al alcance y los eventos seguirán apareciendo desde el área de texto recién agregada. Esto es particularmente útil en entornos de aplicaciones web donde agregas nuevos elementos a la página regularmente.
Otra cosa buena que debe saber sobre el enlace de eventos de jQuery es que no son mutuamente excluyentes. Si agrega otro controlador de clic al mismo elemento que ya tiene uno, simplemente agregará otro. No está sobrescribiendo el anterior. jQuery simplemente maneja esto con bastante gracia para usted. Siempre puede desvincularlos si realmente desea anular una función vinculada previamente.
Si se trata exactamente del mismo evento, vale la pena saber que para desvincular uno específico de ellos y no el otro, deberá asignar un espacio de nombres a los eventos. Eso sucede al usar un punto en el nombre del evento, como click.namespace
.
$("#scope").on("click.one", "textarea", function(event) ( )); $("#scope").on("click.two", "textarea", function(event) ( )); // Just remove the first $("#scope").off("click.one", "textarea");
.off()
, como no lo hemos mencionado antes, es cómo desvincular eventos.
Hay muchos eventos DOM posibles. El clic es el principal obvio, pero hay doble clic, mouseenter y mouseleave, keydown y keyup, formas específicas como desenfoque y cambio, y mucho más. Si está interesado en la lista completa, puede obtener una como esta.
Puede vincular varios eventos al mismo tiempo de esta manera:
$("#scope").on("keydown keyup", "textarea", function(event) ( console.log(event.keyCode); ));
Hay algunas circunstancias en las que está esperando que suceda un evento, pero una vez que sucede, ya no le importa o explícitamente ya no desea activar la función que había vinculado. De eso se trata la .one()
función. Un caso de uso estándar para eso es un botón de envío de formulario (si está manejando con Ajax o lo que sea). Es probable que desee deshabilitar esencialmente ese botón de envío después de que lo hayan presionado hasta que pueda procesar esa información y brindarles la retroalimentación adecuada. Por supuesto, ese no es el único caso de uso, pero tenlo en cuenta. .one()
== solo una vez.