que personalizados lanzar eventos evento escuchador capturar boton añadir asignar agregar javascript javascript-events

personalizados - lanzar evento javascript



¿Qué es el evento que burbujea y captura? (5)

El burbujeo y la captura de eventos son dos formas de propagación de eventos en la API DOM de HTML, cuando ocurre un evento en un elemento dentro de otro elemento, y ambos elementos han registrado un controlador para ese evento. El modo de propagación de eventos determina en qué orden los elementos reciben el evento .

Con el burbujeo, el evento es capturado y manejado primero por el elemento más interno y luego propagado a los elementos externos.

Con la captura, el evento primero es capturado por el elemento más externo y se propaga a los elementos internos.

La captura también se llama "goteo", que ayuda a recordar el orden de propagación:

gotear hacia abajo

En los viejos tiempos, Netscape defendía la captura de eventos, mientras que Microsoft promovía la propagación de eventos. Ambos forman parte de la norma W3C Document Object Model Events (2000).

IE <9 solo utiliza eventos de propagación , mientras que IE9 + y todos los principales navegadores son compatibles con ambos. Por otro lado, el rendimiento de la propagación de eventos puede ser ligeramente inferior para los DOM complejos.

Podemos usar addEventListener(type, listener, useCapture) para registrar los controladores de eventos en modo de burbuja (predeterminado) o de captura. Para usar el modelo de captura pase el tercer argumento como true .

Ejemplo

<div> <ul> <li></li> </ul> </div>

En la estructura anterior, suponga que se produjo un evento de clic en el elemento li .

En la captura del modelo, el evento será manejado por el div primero (haga clic en los manejadores de eventos en el div primero), luego en la ul , luego en el último en el elemento de destino, li .

En el modelo de burbujeo, sucederá lo contrario: el evento será manejado primero por li , luego por ul y por último por el elemento div .

Para más información, ver

En el siguiente ejemplo, si hace clic en cualquiera de los elementos resaltados, puede ver que la fase de captura del flujo de propagación del evento ocurre primero, seguida de la fase de propagación.

var logElement = document.getElementById(''log''); function log(msg) { logElement.innerHTML += (''<p>'' + msg + ''</p>''); } function capture() { log(''capture: '' + this.firstChild.nodeValue.trim()); } function bubble() { log(''bubble: '' + this.firstChild.nodeValue.trim()); } var divs = document.getElementsByTagName(''div''); for (var i = 0; i < divs.length; i++) { divs[i].addEventListener(''click'', capture, true); divs[i].addEventListener(''click'', bubble, false); }

p { line-height: 0; } div { display:inline-block; padding: 5px; background: #fff; border: 1px solid #aaa; cursor: pointer; } div:hover { border: 1px solid #faa; background: #fdd; }

<div>1 <div>2 <div>3 <div>4 <div>5</div> </div> </div> </div> </div> <section id="log"></section>

Otro ejemplo en JSFiddle .

¿Cuál es la diferencia entre el burbujeo de eventos y la captura? De los dos, ¿cuál es el modelo más rápido y mejor de usar?


He encontrado que este tutorial en javascript.info es muy claro al explicar este tema. Y su resumen de 3 puntos al final está realmente hablando de los puntos cruciales. Lo cito aquí:

  1. Los eventos primero se capturan hasta el objetivo más profundo, luego se hacen burbujas. En IE <9 solo burbujean.
  2. Todos los manejadores trabajan en la etapa de propagación excepto addEventListener con el último argumento verdadero, que es la única forma de detectar el evento en la etapa de captura.
  3. Bubble / captura puede ser detenido por event.cancelBubble = true (IE) o event.stopPropagation () para otros navegadores.

Si hay dos elementos, el elemento 1 y el elemento 2. El elemento 2 está dentro del elemento 1 y adjuntamos un controlador de eventos con ambos elementos, por ejemplo, onClick. Ahora, cuando hacemos clic en el elemento 2, se ejecutará eventHandler para ambos elementos. Ahora aquí la pregunta es en qué orden se ejecutará el evento. Si el evento adjunto con el elemento 1 se ejecuta primero, se llama captura de eventos y si el evento adjunto con el elemento 2 se ejecuta primero, esto se denomina burbujeo de eventos. Según W3C, el evento se iniciará en la fase de captura hasta que alcance el objetivo. Vuelva al elemento y luego comience a burbujear.

Los estados de captura y propagación son conocidos por el parámetro useCapture del método addEventListener

eventTarget.addEventListener (type, listener, [, useCapture]);

Por defecto useCapture es falso. Significa que está en la fase de burbujeo.

var div1 = document.querySelector("#div1"); var div2 = document.querySelector("#div2"); div1.addEventListener("click", function (event) { alert("you clicked on div 1"); }, true); div2.addEventListener("click", function (event) { alert("you clicked on div 2"); }, false);

#div1{ background-color:red; padding: 24px; } #div2{ background-color:green; }

<div id="div1"> div 1 <div id="div2"> div 2 </div> </div>

Por favor, intente con el cambio de verdadero y falso.


También está la propiedad Event.eventPhase que puede indicarle si el evento está en el objetivo o si proviene de otro lugar.

Tenga en cuenta que la compatibilidad del navegador no está determinada todavía. Lo probé en Chrome (66.0.3359.181) y Firefox (59.0.3) y es compatible allí.

Ampliando el ya excelente fragmento de la respuesta aceptada , esta es la salida que usa la propiedad eventPhase

var logElement = document.getElementById(''log''); function log(msg) { if (logElement.innerHTML == "<p>No logs</p>") logElement.innerHTML = ""; logElement.innerHTML += (''<p>'' + msg + ''</p>''); } function humanizeEvent(eventPhase){ switch(eventPhase){ case 1: //Event.CAPTURING_PHASE return "Event is being propagated through the target''s ancestor objects"; case 2: //Event.AT_TARGET return "The event has arrived at the event''s target"; case 3: //Event.BUBBLING_PHASE return "The event is propagating back up through the target''s ancestors in reverse order"; } } function capture(e) { log(''capture: '' + this.firstChild.nodeValue.trim() + "; " + humanizeEvent(e.eventPhase)); } function bubble(e) { log(''bubble: '' + this.firstChild.nodeValue.trim() + "; " + humanizeEvent(e.eventPhase)); } var divs = document.getElementsByTagName(''div''); for (var i = 0; i < divs.length; i++) { divs[i].addEventListener(''click'', capture, true); divs[i].addEventListener(''click'', bubble, false); }

p { line-height: 0; } div { display:inline-block; padding: 5px; background: #fff; border: 1px solid #aaa; cursor: pointer; } div:hover { border: 1px solid #faa; background: #fdd; }

<div>1 <div>2 <div>3 <div>4 <div>5</div> </div> </div> </div> </div> <button onclick="document.getElementById(''log'').innerHTML = ''<p>No logs</p>'';">Clear logs</button> <section id="log"></section>


Descripción:

quirksmode.org tiene una buena descripción de esto. En pocas palabras (copiado de quirksmode):

Captura de eventos

Cuando usas captura de eventos

| | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 / / | | | ------------------------- | | Event CAPTURING | -----------------------------------

el controlador de eventos de element1 se activa primero, el controlador de eventos de element2 se activa en último lugar.

Evento burbujeante

Cuando usas un evento burbujeante

/ / ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | -----------------------------------

el controlador de eventos de element2 se activa primero, el controlador de eventos de element1 se activa en último lugar.

¿Qué usar?

Depende de lo que quieras hacer. No hay mejor. La diferencia es el orden de ejecución de los controladores de eventos. La mayoría de las veces estará bien disparar a los manejadores de eventos en la fase de propagación , pero también puede ser necesario dispararlos antes.