Scriptia. Javascript y buenas prácticas en español



Scriptia / artículos / Eventos en jQuery

Eventos en jQuery

Saltar a Anotaciones relacionadas

Presentamos un repaso en profundidad a los métodos de jQuery relacionados con el trabajo con eventos: asignación, manejo (`this` y `target`), desligado de manejadores, disparo _artificial_ de eventos, atajos y buen humor.

## Asignación

El método `bind` asigna a cada elemento seleccionado un manejador para nuestro evento favorito.

$("a").bind("click", function(e) {
	alert("Si te vas y me dejas dime adiós con las orejas");
});

Podemos utilizar los eventos «naturales» del DOM (`click`, `focus`, `mouseover`, etc.) o usar eventos artificiales (hablaremos de ello más adelante). Los métodos abreviados también se mencionan más adelante.

## Manejo

La función asignada como manejador del evento recibe un parámetro, correspondiente a la representación del evento en forma de objeto que podemos utilizar para hacer el mal.

Sus métodos:

  • preventDefault cancela el comportamiento por defecto, esto es, si lo usamos en el manejador del evento clic sobre un enlace, no iremos a parte alguna.

    $("a").bind("click", function(e) {
    	// cancela el comportamiento por defecto
    	e.preventDefault();
    	alert("No te irás, no. Woaaaahhhahaha");
    });
  • stopPropagation evita que el evento burbujee.

    $("a").bind("click", function(e) {
    	// detiene la propagación del evento
    	e.stopPropagation();
    });
    
    $(document.body).bind("click", function(e) {
    	alert("No has atinado con el enlace");
    });

Si quieres evitar tanto el burbujeo como el comportamiento _natural_, lo tienes más fácil todavía: basta con que el manejador devuelva `false`.

$("a").bind("click", function(e) {
	return confirm("¿Verdad que este es un diálogo de besugos?");
});

### Esto y lo otro

¿Y cómo nos referimos al elemento al que hemos asignado el manejador? (Cielos, esto comienza a parecerse al catecismo en preguntas y respuestas.) Sencillo: usamos `this`.

$("a").bind("click", function(e) {
	alert("Marchando una de " + this.href);
});

Ahora bien, hay casos en los que interesa asignar el manejador a un elemento ancestro del que queremos manipular, por ejemplo, para tratar con celdas de una tabla…

$("table tbody td").bind("click", function(e) {
});

… podemos asignar el manejador a su padre, ahorrando así la iteración por las choricientas celdas de la tabla para asignar eventos (dicha iteración existe, aunque tú no la veas). Vaya, mejor así:

$("table tbody").bind("click", function(e) {
});

En este caso `this` ya no nos resulta útil; para acceder al elemento sobre el que _se ha actuado_ usamos la propiedad `target` del objeto que representa el evento. Para dar con la celda, basta con usar `parents`:

$("table tbody").click(function(e) {
	var t = $(e.target);
	(t.is("td") ? t : t.parents("td")).toggleClass("selected");
});

## Limpieza

Para eliminar manejadores, disponemos del método `unbind`. En tres sabores:

* `$(”a”).unbind(”click”, theHandler)` elimina la función `theHandler` de la cadena de manejadores del evento clic.

* `$(”a”).unbind(”click”)` elimina todos los manejadores del evento clic.

* `$(”a”).unbind()` elimina todos los manejadores de eventos asignados hasta el momento.

## Disparo

`trigger` es tu amigo:

$("tbody input[@type=checkbox]") // recogemos los checkboxes
	.bind("click", function() { // asignamos un manejador para el evento `click`
		$(this) // añadimos o eliminamos una clase en el registro que lo contiene
			.parents("tr")[ this.checked ? "addClass" : "removeClass" ]("selected");
	})
	// disparamos el evento para asignar los estilos según los estados iniciales
	.trigger("click");

Y te permite trabajar con eventos _sintéticos_. He aquí un ejemplo inútil pero inteligible:

$("#counter").bind("fakeevent", function() {
	this.innerHTML = +this.innerHTML + 1;
});

$("input[@type=checkbox]").bind("click", function(e) {
	$("#counter").trigger("fakeevent");
});

Esto es, cada vez que se dispare un evento clic en un checkbox, el contador (`#counter`) lo registrará.

## En el principio hubo un `ready`

Ya conoces `$(document).ready(f)`. ¿No? Oh, te lo presento: permite ejecutar una función en cuanto el árbol DOM esté completo.

function init() {
	// mueve las caderas
}

$(document).ready(init);

Es un sustituto ideal para `window.onload`, `addLoadEvent` y otros, pues con `ready` no es necesario esperar a que se complete la carga de las imágenes.

`ready` también tiene una forma abreviada: basta con ejecutar `$` con una función como parámetro…

$(init);

… para que se ejecute lo antes posible.

### Cosas que quizá no sepas

* Puedes usar `ready` cuantas veces quieras.

* Las funciones se ejecutan en el mismo orden en que se han añadido a la cola.

* Si usas `ready` cuando el documento _ya está_ completo, la función se ejecuta inmediatamente.

## `toggle`, cadencioso y tropical

El método `toggle` acepta dos funciones que usará como manejadores del evento `click` alternativamente:

$("a").toggle(
	function() { alert("impar"); },
	function() { alert("par"); }
);

## `hover`

`hover` recibe dos funciones. La primera de ellas se ejecuta al situar el ratón sobre el elemento, la segunda al abandonarlo. Ejemplo clásico:

$("tr").hover(
	function() { $(this).addClass("hover"); },
	function() { $(this).removeClass("hover"); }
);

## Lazy coding

Si `$(”#foo”).bind(”click”, f);` y `$(”#foo”).unbind(”click”, f);` es demasiado escribir para ti, dispones de métodos auxiliares:

* `blur`
* `change`
* `click`
* `focus`
* `dblclick`
* `error`
* `focus`
* `keydown`
* `keypress`
* `keyup`
* `load`
* `mousedown`
* `mousemove`
* `mouseout`
* `mouseover`
* `mouseup`
* `resize`
* `scroll`
* `select`
* `submit`

Puedes usarlos pasando una función para asignar un manejador:

function clickHandler(e) {
	alert(this.href);
	e.preventDefault();
}

$("a").click(clickHandler);

Sin parámetro alguno, para disparar el evento:

$("a").click();

Con el prefijo `un` para desligar un manejador:

$("a").unclick(clickHandler);

O todos los manejadores:

$("a").unclick();

Y, joyita, con un `one` por delante, el evento solo se disparará una vez (de hecho, se desvinculará al ejecutarse):

$("a").oneclick(function(e) {
	alert("La próxima te dejo pasar");
	e.preventDefault();
});

**Advertencia:** es posible que estos _métodos para vagos_ migren a un plugin en próximas versiones de jQuery. No los utilices en código que vayas a distribuir (_pulguines_ y demás).

Otro día hablaremos de los eventos relacionados con AJAX.



16 comentarios RSS

1 Carlitus (2006-12-28 @ 11:41 pm):

Muy bueno el tutorial de JQuery, ya estás a un paso menos de hacerte rico y famoso :P

2 Sergio Sam (2007-03-02 @ 1:14 pm):

muy bueno pero todos los tutoriales de JQuery se pusieron de acuerdo para poner lo basico y todos prometieron ejemplos con ajax… pero nadie puso ningungo :-( ya vi 3 tutoriales en español y nada … seria mucho pedir un ejemplito de ajax :-)

3 choan (2007-03-05 @ 12:06 pm):

Sergio, razón llevas.

Por desgracia, mis obligaciones no me permiten ocuparme de este blog como sus lectores merecen. Pongo en cola tu sugerencia, aunque no prometo nada.

Un saludo.

4 Wil Wzk (2007-03-06 @ 3:17 am):

…¿cómo pepinos hizo el amigo choan para escribir desde el futuro..?

…bueno, para los que no sabían, jQuery ya pasó arriba de la versión 1.0.1 y efectivamente, los atajos (ver lazy coding) ya se suprimieron y ahora deben agregarse vía un plugin, así que… al que no quiera dolores de cabeza, a utilizar los métodos bind y unbind

…sobre el tema de ajax, bueno, pues… paciencia, paciencia…

5 choan (2007-03-07 @ 5:44 pm):

Wil, no escribí desde el futuro. (Bueno, sí, lo hice, pero siempre lo negaré.) Tenía un error en la plantilla de comentarios que hacía que… mejor me callo, que me haréis pasar vergüenza.

En cuanto a los atajos: se mantienen click, keypress y similares (tanto para asignar manejadores como para disparar el evento artificialmente). Han desaparecido los métodos unblabla y oneblabla, quedando disponibles, para lo que fuere menester, los métodos one y unbind.

6 Tomás (2007-03-09 @ 8:10 pm):

amo el jQuery desde que lo conocí jaja. Este blog lo calificaría con un 10!!!! Pero no soy el dueño así que un 9 :P jajaj

Felicitaciones a todos… son todos Dios para mí xD

7 Carlos Garcia (2007-04-05 @ 5:27 am):

muy bueno exelente

8 Barbara (2007-05-08 @ 4:11 pm):

Hola, a ver si me podéis ayudar con el binding de eventos a contenido dinámico…

El problema que tengo es que no puedo asignar un handler para el evento submit de elementos generados dinámicamente (sean o no resultado de una petición Ajax). He probado algunas soluciones, como la que plantea Jonathan Chaffer en
http://groups.google.com/group/jquery-en/browse_thread/thread/8d6abc5c9b1a4fa0/39b2a35eb856c5ec?lnk=gst&q=bindbehaviors&rnum=2#39b2a35eb856c5ec pero sólo me funciona la opción Event Bubbling y únicamente en Firefox. En IE la técnica del Bubbling sólo me funciona para eventos distintos de submit…

Quisiera saber si alguien más ha tenido este problema y cómo lo ha solucionado
Gracias!!

9 choan (2007-05-13 @ 5:38 pm):

Particularmente, no he tenido ningún problema en la asignación de manejadores para submit en contenido creado dinámicamente.

Si sigues con el temita, te propongo enviar la consulta y el código a la lista de jQuery en español.

Salud.

10 Krles (2007-06-06 @ 10:33 am):

Hola.
Llevo una semana con jQuery y lo encuentro súper práctico. En cuanto al tutorial, por lo que voy leyendo buena nota también.

Acabo de encallarme con el tema del código generado dinámicamente. Un div que contiene una tabla i un botón, utilizo hover para resaltar elementos y click para seleccionarlos, el botón cierra la ventana. Cuando reescribo los elementos de diversas maneras ( $(”selector”).html(”código”) o $(”selector”).prepend(”código”) dejan de responder.

El selector es por id CSS, el código jQuery está dentro de $(document).ready(function(){ … }), el js que reescribe la página está en una función aparte que llamo desde dentro de $(”selector”).click(function(){ funcionGeneraCodigo(); }

Si alguien ve algo mal que me lo indique porfa. Mientras voy a ver qué se cuentan por la lista de jQuery en español.

Saludos a todos.

11 Carlos (2007-07-20 @ 12:34 pm):

Mi enhorabuena, me ha venido el artículo de puta madre.
Saludetes

12 javier (2007-09-10 @ 1:43 am):

Esta librería tiene muchas ventajas evidentes, se me ocurren varias que pueden optimizar mucho el código respecto a las etiquetas CSS. Por ejemplo formatear los enlaces externos con una clase en especial.

13 sonia (2007-09-18 @ 12:46 pm):

Hola, alguien me podria decir si existe en jquery una funcion que cargue en un div el contenido q le pasas tal cual, por ejemplo algo asi:
$(”div#miDiv”).LA_FUNCION(Columna 1>Columna 2);
y que me hiciera mi fila con mis dos celdas dnd está puesto el div?
Muchas gracias

14 Josekus (2008-04-23 @ 3:34 am):

Holaaaaaa uauu hoy dia estuve deciciendo si irme por prototype o por jquery, Bro has decidio eld estino XD.. Gracielas esta demasiado bueno tu articulo . Suerte Compa

15 choan (2008-10-11 @ 5:54 pm):

Walo, sí, una sugerencia: sigue leyendo. Lo descrito en Ajax, eventos y jQuery también vale para elementos generados dinámicamente.

16 willy (2009-05-18 @ 3:18 am):

hola
estado trabajando con jquery el el código siguiente al hacer click sobre register se abre la ventana doalog, pero cuando vuelvo a intentarlo ya no funciona, ¿tienes alguna idea de por que pasa esto?
$(function() {
$(”#aRegister”).click(function(e){
$(”#divRegister”).dialog({
bgiframe :true,
modal:true
});
});
});


Acerca de Scriptia

Saltar a la caja de búsqueda

Scriptia forma parte del PDM de Choan C. Gálvez, desarrollador web residente en Barcelona. Scriptia pretende mejorar la calidad de la documentación acerca de javascript disponible en español.