Eventos
Cuando un usuario interactúa con una aplicación, se producen una serie de eventos (de teclado, ratón, etc.) que nuestro código debería manejar de forma adecuada. Hay muchos eventos que pueden ser capturados y procesados (listado aquí). Veremos algunos de los más comunes.
Algunos tipos de eventos
En este apartado veremos un pequeño subconjunto de los eventos que pueden ser generados durante la ejecución de una aplicación web. Estos eventos pueden ser generados por interacción con el usuario (ratón, teclado, ...) o cuando se produce algún hito durante la ejecución del programa (carga, animaciones, impresora, ....).
Puedes consultar los tipos de eventos existentes en la página oficial de MDN. Ahí encontrarás para cada tipo, uno o varios enlaces a la lista de eventos concretos y su documentación. A continuación veremos algunos de esos eventos:
Eventos de teclado
- keydown → El usuario presiona una tecla. Si la tecla se mantiene pulsada durante un tiempo, este evento se generará de forma repetida.
- keyup → Ocurre cuando el usuario deja de presionar la tecla
- keypress → Parecido a keydown. Acción de pulsar y levantar.
Eventos de ratón
- click → Este evento ocurre cuando el usuario pulsa un elemento (presiona y levanta el dedo del botón → mousedown + mouseup). También se lanza cuando un evento táctil de toque (tap) es recibido.
- dblclick → Se lanza cuando se hace un doble click sobre el elemento.
- mousedown → Parecido a keydown. Acción de pulsar y levantar.
- mouseup → Este evento ocurre cuando el usuario levanta el dedo del botón del ratón.
- mouseenter → Se lanza cuando el puntero del ratón entra en el elemento.
- mouseleave → Se lanza cuando el puntero del ratón sale del elemento.
- mousemove → Este evento se llama repetidamente cuando el puntero de un ratón se mueve mientras está dentro de un elemento.
Eventos táctiles
- touchstart → Se lanza cuando se detecta un toque en la pantalla táctil.
- touchend → Se lanza cuando se levanta el dedo de la pantalla.
- touchmove → Se lanza cuando un dedo es desplazado a través de la pantalla.
- touchcancel → Este evento ocurre cuando se interrumpe un evento táctil.
Eventos de formulario
- focus → Este evento se ejecuta cuando un elemento (no sólo un elemento de un formulario) tiene el foco (es seleccionado o está activo).
- blur → Se ejecuta cuando un elemento seleccionado pierde el foco.
- change → Se ejecuta cuando el contenido, selección o estado del checkbox de un elemento cambia (sólo <input>, <select>, y <textarea>).
- input → Este evento se produce cuando el valor de un elemento <input> o <textarea> cambia.
- select → Este evento se lanza cuando el usuario selecciona un texto de un <input> o <textarea>.
- submit → Se lanza cuando un formulario es enviado (el envío puede ser cancelado). Se aplica al elemento <form>.
Manejo de Eventos
Hay muchas formas de asignar un código o función a un determinado evento. Vamos a ver las dos formas posibles (para ayudar a entender código hecho por otros), pero el recomendado (y la forma válida para este curso) es usar event listeners.
Manejo de eventos clásico
Lo primero de todo, podemos poner código JavaScript (o llamar a una función) en un atributo de un elemento HTML. Estos atributos se nombran como los eventos, pero con el prefijo 'on' (click → onclick).
Si llamamos a una función, podemos pasarle como parámetros la palabra reservada this y event pasar una referencia al elemento HTML (afectado por el evento) y el objeto con información del evento. Vamos a ver un ejemplo del evento click.
Podemos añadir una función manejadora de evento desde código a un elemento desde la propiedad correspondiente (onclick, onfocus, …), o asignarles el valor null si queremos dejar de escuchar algún evento. Si utilizamos una funcón anónima en lugar de una función flecha, podremos acceder al objeto this, que representará el elemento que recibe el evento.
Event listeners (recomendado)
El método para manejar eventos explicado arriba tiene algunas desventajas, por ejemplo, no se pueden gestionar varias funciones manejadoras para un mismo evento, ni tampoco elegir como se propaga el evento (ver más adelante).
Para añadir un event listener, usamos el método addEventListener sobre el elemento. Este método recibe al menos dos parámetros. El nombre del evento (una cadena) y un manejador (función anónima o nombre de una función existente).
Podemos añadir tantos manejadores como queramos. Sin embargo, si queremos eliminar un manejador, debemos indicar qué función estamos eliminando.
Objeto del evento
El objeto del evento es creado por JavaScript y pasado al manejador como parámetro. Este objeto tiene algunas propiedades generales (independientemente del tipo de evento) y otras propiedades específicas (por ejemplo, un evento del ratón tiene las coordenadas del puntero, etc.).
Estas son algunas propiedades generales que tienen todos los eventos:
- target → El elemento HTML que recibe el evento.
- type → El nombre del evento: 'click', 'keypress', …
- cancelable → Devuelve true o false. Si el evento se puede cancelar significa que llamando a event.preventDefault() se puede anular la acción por defecto (El envío de un formulario, el click de un enlace, etc…).
- bubbles → Devuelve cierto o falso dependiendo de si el evento se está propagando (Lo veremos más adelante).
- preventDefault() → Este método previene el comportamiento por defecto (cargar una página cuando se pulsa un enlace, el envío de un formulario, etc.).
- stopPropagation() → Previene la propagación del evento (ver propagación de eventos más adelante).
- stopImmediatePropagation() → Si el evento tiene más de un manejador, se llama a este método para prevenir la ejecución del resto de manejadores.
Dependiendo del tipo de evento, el objeto tendrá diferentes propiedades:
MouseEvent
Este objeto representa un evento que se ha producido por la acción del usuario sobre el ratón (click, movimiento).
- button → Devuelve el botón del ratón que lo ha pulsado (0: botón izquierdo, 1: la rueda del ratón, 2: botón derecho).
- clientX, clientY → Coordenadas relativas del ratón en la ventana del navegador cuando el evento fue lanzado.
- pageX, pageY → Coordenadas relativas del documento HTML, si se ha realizado alǵun tipo de desplazamiento (scroll), este será añadido (usando clientX y clientY no se añade).
- screenX, screenY → Coordenadas absolutas del ratón en la pantalla.
- detail → Indica cuántas veces el botón del ratón ha sido pulsado (un click, doble, o triple click).
KeyboardEvent
Este objeto representa un evento que se produce por la interacción del usuario a través del teclado.
- key → Devuelve el nombre de la tecla pulsada.
- keyCode → Devuelve el código del carácter Unicode en el evento keypress, keyup o keydown.
- altKey, ctrlKey, shiftKey, metaKey → Devuelven si las teclas "alt", "control", "shift" o "meta" han sido pulsadas durante el evento (Bastante útil para las combinaciones de teclas como ctrl+c). El objeto MouseEvent también tiene estas propiedades.
Propagación de eventos (bubbling)
Muchas veces, hay elementos en una web que se solapan con otros elementos (están contenidos dentro). Por ejemplo, si pulsamos sobre un párrafo que está contenido en un elemento <div>, ¿el evento se ejecutará en el párrafo, en el <div> o en ambos? ¿Cuál se ejecuta primero?.
Por ejemplo, vamos a ver qué ocurre con estos dos elementos (un elemento div dentro de otro div) cuando hacemos clic en ellos.
Si hacemos click sobre el elemento rojo #div1, se imprimirá solo "Has pulsado: div1". Sin embargo, si pulsamos sobre el elemento azul #div2 (el cual está dentro del elemento rojo) imprimirá ambos mensajes (#div2 primero).
En conclusión, primero se recibe el evento en el elemento sobre el cual actuamos, y después se propaga a los elementos contenedores (incluido document). Esto se llama event bubbling. Podemos invertir el orden este proceso añadiendo un tercer parámetro al método addEventListener y establecerlo a true. Esto sería la captura de evento.
La propiedad eventPhase del evento, nos indicará la fase de propagación en la que estamos: 1. Captura (parámetro a true), 2: Target o elemento que recibe el evento, 3: Bubble (por defecto)
