Explicación de los eventos de JavaScript

JavaScript en el navegador utiliza un modelo de programación basado en eventos. Todo comienza siguiendo un evento. Esta es una introducción a los eventos de JavaScript y cómo funciona el manejo de eventos.

Introducción

JavaScript en el navegador utiliza un modelo de programación basado en eventos.

Todo comienza siguiendo un evento.

El evento podría ser el DOM está cargado, o una solicitud asincrónica que termina de buscar, o un usuario que hace clic en un elemento o se desplaza por la página, o que el usuario escribe en el teclado.

Hay muchos tipos diferentes de eventos.

Controladores de eventos

Puede responder a cualquier evento utilizando unControlador de eventos, que es una función que se llama cuando ocurre un evento.

Puede registrar varios controladores para el mismo evento, y todos serán llamados cuando ocurra ese evento.

JavaScript ofrece tres formas de registrar un controlador de eventos:

Controladores de eventos en línea

Este estilo de controladores de eventos se usa muy raramente en la actualidad, debido a sus limitaciones, pero era la única forma en los primeros días de JavaScript:

<a href="site.com" onclick="dosomething();">A link</a>

Controladores de eventos en DOM

Esto es común cuando un objeto tiene como máximo un controlador de eventos, ya que no hay forma de agregar varios controladores en este caso:

window.onload = () => {
  //window loaded
}

Se utiliza con mayor frecuencia al manipularXHRpeticiones:

const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
  //.. do something
}

Puede verificar si un controlador ya está asignado a una propiedad usandoif ('onsomething' in window) {}.

UsandoaddEventListener()

Este es elmanera moderna. Este método permite registrar tantos manejadores como necesitemos, y es el más popular que encontrarás:

window.addEventListener('load', () => {
  //window loaded
})

Tenga en cuenta que IE8 y versiones anteriores no admitían esto y, en su lugar, usaban su propioattachEvent()API. Téngalo en cuenta si necesita admitir navegadores más antiguos.

Escuchar diferentes elementos

Puedes escuchar enwindowpara interceptar eventos "globales", como el uso del teclado, y puede escuchar elementos específicos para verificar los eventos que ocurren en ellos, como un clic del mouse en un botón.

Esta es la razón poraddEventListenera veces se llamawindow, a veces en un elemento DOM.

El objeto de evento

Un controlador de eventos obtiene unEventobjeto como primer parámetro:

const link = document.getElementById('my-link')
link.addEventListener('click', event => {
  // link clicked
})

Este objeto contiene muchas propiedades y métodos útiles, como:

  • target, el elemento DOM que originó el evento
  • type, el tipo de evento
  • stopPropagation(), llamado para dejar de propagar el evento en el DOM

(ver la lista completa).

Otras propiedades son proporcionadas por tipos específicos de eventos, comoEventes una interfaz para diferentes eventos específicos:

Cada uno de ellos tiene una página MDN vinculada, por lo que puede inspeccionar todas sus propiedades.

Por ejemplo, cuando ocurre un KeyboardEvent, puede verificar qué tecla se presionó, en un formato legible (Escape,Entery así sucesivamente) marcando elkeypropiedad:

window.addEventListener('keydown', event => {
  // key pressed
  console.log(event.key)
})

En un evento de mouse, podemos verificar qué botón del mouse se presionó:

const link = document.getElementById('my-link')
link.addEventListener('mousedown', event => {
  // mouse button pressed
  console.log(event.button) //0=left, 2=right
})

Generación de eventos y captura de eventos

El burbujeo y la captura son los 2 modelos que utilizan los eventos para propagarse.

Suponga que su estructura DOM es

<div id="container">
  <button>Click me</button>
</div>

Desea realizar un seguimiento cuando los usuarios hacen clic en el botón y tiene 2 oyentes de eventos, uno enbuttony uno en#container. Recuerde, un clic en un elemento hijo siempre se propagará a sus padres, a menos que detenga la propagación (ver más adelante).

Se llamará a esos oyentes de eventos en orden, y este orden está determinado por el modelo de generación / captura de eventos utilizado.

Burbujeantesignifica que el evento se propaga desde el elemento en el que se hizo clic (el hijo) hasta todo su árbol padre, comenzando por el más cercano.

En nuestro ejemplo, el controlador debuttondisparará antes del#containermanipulador.

Capturandoes lo contrario: los controladores de eventos externos se activan antes que el controlador más específico, el que está enbutton.

Por defecto, todas las burbujas de eventos.

Puede optar por adoptar la captura de eventos aplicando un tercer argumento a addEventListener, configurándolo entrue:

document.getElementById('container').addEventListener(
  'click',
  () => {
    //window loaded
  },
  true
)

Tenga en cuenta queprimero se ejecutan todos los controladores de eventos de captura.

Luego, todos los controladores de eventos burbujeantes.

El orden sigue este principio: el DOM recorre todos los elementos a partir del objeto Ventana y busca el elemento en el que se hizo clic. Mientras lo hace, llama a cualquier controlador de eventos asociado al evento (fase de captura).

Una vez que alcanza el objetivo, repite el viaje hasta el árbol principal hasta el objeto Ventana, llamando de nuevo a los controladores de eventos (fase de propagación).

Detener la propagación

Un evento en un elemento DOM se propagará a todo su árbol de elementos padre, a menos que se detenga.

<html>
  <body>
    <section>
      <a id="my-link" ...>

Un evento de clic enase propagará asectiony luegobody.

Puede detener la propagación llamando alstopPropagation()método de un evento, generalmente al final del controlador de eventos:

const link = document.getElementById('my-link')
link.addEventListener('mousedown', event => {
  // process the event
  // ...

  event.stopPropagation()
})

Aquí hay una lista de los eventos más comunes que probablemente manejará.

Carga

loadse dispara sobrewindowy elbodyelemento cuando la página ha terminado de cargarse.

Eventos del mouse

clickse dispara cuando se hace clic en un botón del mouse.dblclickcuando se hace clic dos veces con el mouse. Por supuesto que en este casoclickse dispara justo antes de este evento.mousedown,mousemoveymouseupse puede utilizar en combinación para realizar un seguimiento de los eventos de arrastrar y soltar. Ten cuidado conmousemove, ya que dispara muchas veces durante el movimiento del mouse (verestrangulamientomás tarde)

Eventos de teclado

keydownse dispara cuando se presiona un botón del teclado (y cada vez que la tecla se repite mientras el botóncorsépresionado).keyupse dispara cuando se suelta la tecla.

Desplazarse

losscrollel evento se dispara enwindowcada vez que se desplaza por la página. Dentro del controlador de eventos, puede verificar la posición de desplazamiento actual marcandowindow.scrollY.

Tenga en cuenta que este evento no se realiza una sola vez. Se dispara muchas veces durante el desplazamiento, no solo al final o al comienzo del desplazamiento, por lo que no realice ningún cálculo o manipulación pesada en el controlador: utiliceestrangulamientoen lugar de.

Estrangulamiento

Como mencionamos anteriormente,mousemoveyscrollson dos eventos que no se activan una vez por evento, sino que llaman continuamente a su función de controlador de eventos durante toda la duración de la acción.

Esto se debe a que proporcionan coordenadas para que pueda rastrear lo que está sucediendo.

Si realiza una operación compleja en el controlador de eventos, afectará el rendimiento y provocará una experiencia lenta para los usuarios de su sitio.

Bibliotecas que proporcionan estrangulamiento comoLodashimpleméntelo en más de 100 líneas de código, para manejar todos los casos de uso posibles. Una implementación simple y fácil de entender es esta, que usasetTimeoutpara almacenar en caché el evento de desplazamiento cada 100 ms:

let cached = null
window.addEventListener('scroll', event => {
  if (!cached) {
    setTimeout(() => {
      //you can access the original event at `cached`
      cached = null
    }, 100)
  }
  cached = event
})

Más tutoriales de js: