No se puede entender el parámetro useCapture en addEventListener

Resuelto user26732 asked hace 13 años • 9 respuestas

Leí el artículo en https://developer.mozilla.org/en/DOM/element.addEventListener pero no puedo entender useCaptureel atributo. Definición hay:

Si es verdadero, useCapture indica que el usuario desea iniciar la captura. Después de iniciar la captura, todos los eventos del tipo especificado se enviarán al oyente registrado antes de enviarse a cualquier EventTarget debajo de él en el árbol DOM. Los eventos que se propagan hacia arriba a través del árbol no activarán un oyente designado para utilizar la captura.

En este código, el evento principal se activa antes que el secundario, por lo que no puedo entender su comportamiento. El objeto de documento tiene usecapture verdadero y el div secundario tiene usecapture establecido en falso y se sigue usecapture del documento. Entonces, ¿por qué se prefiere la propiedad del documento a la secundaria?

function load() {
  document.addEventListener("click", function() {
    alert("parent event");
  }, true);

  document.getElementById("div1").addEventListener("click", function() {
    alert("child event");
  }, false);
}
<body onload="load()">
  <div id="div1">click me</div>
</body>
Expandir fragmento

user26732 avatar Sep 13 '11 14:09 user26732
Aceptado

Los eventos se pueden activar en dos ocasiones: al principio ("captura") y al final ("burbuja"). Los eventos se ejecutan en el orden en que se definen. Digamos que defines 4 detectores de eventos:

window.addEventListener("click", function(){console.log(1)}, false);
window.addEventListener("click", function(){console.log(2)}, true);
window.addEventListener("click", function(){console.log(3)}, false);
window.addEventListener("click", function(){console.log(4)}, true);
Expandir fragmento

Los mensajes de registro aparecerán en este orden:

  • 2(definido primero, usando capture=true)
  • 4(definido segundo usando capture=true)
  • 1(primer evento definido con capture=false)
  • 3(segundo evento definido con capture=false)
Rob W avatar Sep 13 '2011 07:09 Rob W

Este diagrama me parece muy útil para comprender las fases de captura/objetivo/burbuja: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases

A continuación, contenido extraído del enlace.

Etapas

El evento se envía siguiendo una ruta desde la raíz del árbol hasta este nodo de destino. Luego se puede manejar localmente en el nivel del nodo objetivo o desde los ancestros de cualquier objetivo que se encuentren más arriba en el árbol. El envío de eventos (también llamado propagación de eventos) ocurre en tres fases y en el siguiente orden:

  1. La fase de captura: el evento se envía a los antepasados ​​del objetivo desde la raíz del árbol hasta el padre directo del nodo objetivo.
  2. La fase de destino: el evento se envía al nodo de destino.
  3. La fase de burbujeo: el evento se envía a los antepasados ​​del objetivo desde el padre directo del nodo objetivo hasta la raíz del árbol.

representación gráfica de un evento enviado en un árbol DOM utilizando el flujo de eventos DOM

Los antepasados ​​del objetivo se determinan antes del envío inicial del evento. Si el nodo objetivo se elimina durante el envío, o se agrega o elimina un ancestro del objetivo, la propagación del evento siempre se basará en el nodo objetivo y los ancestros del objetivo determinados antes del envío.

Es posible que algunos eventos no cumplan necesariamente las tres fases del flujo de eventos DOM; por ejemplo, el evento solo podría definirse para una o dos fases. Como ejemplo, los eventos definidos en esta especificación siempre cumplirán las fases de captura y destino, pero algunos no cumplirán la fase de burbujeo ("eventos burbujeantes" versus "eventos no burbujeantes", consulte también el atributo Event.bubbles).

lax4mike avatar May 18 '2012 14:05 lax4mike

Captura de evento ( useCapture = true) frente a evento de burbuja ( useCapture = false)

Referencia de MDN

  • El evento de captura se enviará antes del evento de burbuja
  • El orden de propagación de eventos es
    1. Captura de padres
    2. Captura de niños
    3. Captura de objetivo y burbuja de objetivo
      • En el orden en que fueron registrados.
      • Cuando el elemento es el objetivo del evento, useCaptureel parámetro no importa (Gracias @bam y @legend80s)
    4. Burbuja de niños
    5. Burbuja para padres
  • stopPropagation()detendrá el flujo

utilizar flujo de captura

Manifestación

Resultado:

  1. Captura de padres

  2. Burbuja objetivo 1

    (Debido a que Capture y Bubble of Target se activarán en el orden en que fueron registrados, este se activa primero)

  3. Captura de objetivos

  4. Burbuja objetivo 2

  5. Burbuja para padres

var parent = document.getElementById('parent');
var target = document.getElementById('target');

// "target" will trigger in the order of register (addEventListener()), capture / bubble don't affect the order
// #2
target.addEventListener('click', function (e) { 
console.log('Target Bubble 1');
// e.stopPropagation();
}, false);

// #3
target.addEventListener('click', function (e) { 
console.log('Target Capture');
// e.stopPropagation();
}, true);

// #4
target.addEventListener('click', function (e) { 
console.log('Target Bubble 2');
// e.stopPropagation();
}, false);

// #1 : "parent capture" first
parent.addEventListener('click', function (e) { 
console.log('Parent Capture');
// e.stopPropagation();
}, true);

// #5 : "parent bubble" last
parent.addEventListener('click', function (e) { 
console.log('Parent Bubble');
// e.stopPropagation();
}, false);
<div id="parent">
    <button id="target" style="padding: 1em 0.8em;">
        Trigger event
    </button>
</div>
Expandir fragmento

Steely Wing avatar Mar 04 '2014 06:03 Steely Wing

Cuando dices useCapture = true, los eventos se ejecutan de arriba a abajo en la fase de captura; cuando es false, hace una burbuja de abajo hacia arriba.

sushil bharwani avatar Sep 13 '2011 07:09 sushil bharwani