No se puede comprender el parámetro useCapture en addEventListener

He leído el artículo en https://developer.mozilla.org/en/DOM/element.addEventListener pero no useCapture entender el atributo useCapture . Definición allí es:

Si es verdadero, use Capture 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 ser enviados a cualquier EventTargets debajo de él en el árbol DOM. Los eventos que burbujean hacia arriba a través del árbol no activarán a un oyente designado para usar la captura.

En este código, el evento padre se desencadena antes que el hijo, por lo que no puedo entender su comportamiento. El objeto document tiene usecapture true y child div tiene usecapture set false y document usecapture seguido. Por eso, la propiedad document es preferible a child.

 function load() { document.addEventListener("click", function() { alert("parent event"); }, true); document.getElementById("div1").addEventListener("click", function() { alert("child event"); }, false); } 
  
click me

Los eventos se pueden activar en dos ocasiones: al comienzo (“captura”) y al final (“burbuja”). Los eventos se ejecutan en el orden de cómo están definidos. Digamos que defines 4 oyentes de eventos:

 window.addEventListener("click", function(){alert(1)}, false); window.addEventListener("click", function(){alert(2)}, true); window.addEventListener("click", function(){alert(3)}, false); window.addEventListener("click", function(){alert(4)}, true); 

Encuentro que este diagtwig es muy útil para comprender las fases de captura / objective / 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.

Fases

El evento se envía siguiendo una ruta desde la raíz del árbol hasta este nodo de destino. Luego puede manejarse localmente en el nivel de nodo objective o desde los antepasados ​​de cualquier objective 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 objective desde la raíz del árbol hasta el padre directo del nodo objective.
  2. La fase objective: el evento se envía al nodo objective.
  3. La fase de burbujeo: el evento se envía a los antepasados ​​del objective desde el padre directo del nodo de destino 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 objective se determinan antes del envío inicial del evento. Si el nodo objective se elimina durante el envío, o si se agrega o quita el antecesor del objective, la propagación del evento siempre se basará en el nodo objective y los antepasados ​​del objective determinados antes del envío.

Algunos eventos pueden no necesariamente cumplir las tres fases del flujo de eventos DOM, por ejemplo, el evento solo se puede definir para una o dos fases. Como ejemplo, los eventos definidos en esta especificación siempre cumplirán las fases de captura y objective, pero algunos no lograrán la fase de burbujeo (“eventos de burbujeo” frente a “eventos que no burbujean”, ver también el atributo Event.bubbles).

Evento Capture vs Bubble Event

  • El evento de captura se enviará antes del evento Bubble
  • La orden de propagación del evento es
    1. Captura de los padres
    2. Captura de niños
    3. Burbuja de los niños
    4. Burbuja de los padres

( stopPropagation() detendrá el flujo)

  | A -----------------|--|----------------- | Parent | | | | -------------|--|----------- | | |Children V | | | | ---------------------------- | | | -------------------------------------- 

Manifestación

 var parent = document.getElementById('parent'), child = document.getElementById('child'); child.addEventListener('click', function(e){ console.log('Child Capture, with capture'); // e.stopPropagation(); }, true); child.addEventListener('click', function(e){ console.log('Child Bubble'); // e.stopPropagation(); }, false); parent.addEventListener('click', function(e){ console.log('Parent Capture, with capture'); // e.stopPropagation(); }, true); parent.addEventListener('click', function(e){ console.log('Parent Bubble'); // e.stopPropagation(); }, false); 
 

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

Ejemplo de código:

 
Outer Div
Inner Div

Código Javascript:

 d1 = document.getElementById("div1"); d2 = document.getElementById("div2"); 

si ambos se establecen en falso

 d1.addEventListener('click',function(){alert("Div 1")},false); d2.addEventListener('click',function(){alert("Div 2")},false); 

Se ejecuta: Al hacer clic en Div interior, las alertas se muestran como: Div 2> Div 1

Aquí el script se ejecuta desde el elemento interno: Event Bubbling (useCapture se ha configurado en falso)

div 1 se establece en true y div 2 se establece en false

 d1.addEventListener('click',function(){alert("Div 1")},true); d2.addEventListener('click',function(){alert("Div 2")},false); 

Ejecuta: Al hacer clic en Div interior, las alertas se muestran como: Div 1> Div 2

Aquí el script se ejecuta desde el ancestro / elemento externo: Event Capturing (useCapture se ha configurado en verdadero)

div 1 se establece en false y div 2 se establece en true

 d1.addEventListener('click',function(){alert("Div 1")},false); d2.addEventListener('click',function(){alert("Div 2")},true); 

Se ejecuta: Al hacer clic en Div interior, las alertas se muestran como: Div 2> Div 1

Aquí el script se ejecuta desde el elemento interno: Event Bubbling (useCapture se ha configurado en falso)

div 1 se establece en true y div 2 se establece en true

 d1.addEventListener('click',function(){alert("Div 1")},true); d2.addEventListener('click',function(){alert("Div 2")},true); 

Ejecuta: Al hacer clic en Div interior, las alertas se muestran como: Div 1> Div 2

Aquí el script se ejecuta desde el ancestro / elemento externo: Captura de eventos ya que useCapture se ha establecido en true

Se trata de modelos de eventos: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow Puede capturar eventos en fase de burbujeo o en fase de captura. Tu elección.
Eche un vistazo a http://www.quirksmode.org/js/events_order.html ; lo encontrará muy útil.

Dadas las tres fases del viaje del evento:

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

useCapture indica para qué fases se useCapture el evento:

Si es true , useCapture indica que el usuario desea agregar el detector de eventos únicamente para la fase de captura, es decir, este detector de eventos no se activará durante las fases objective y de burbujeo. Si es false , el detector de eventos solo se activará durante las fases objective y de burbujeo

La fuente es la misma que la segunda mejor respuesta: https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases

El orden de definición solo importa si los artículos están en el mismo nivel. Si invierte el orden de definición en su código obtendrá los mismos resultados.

Sin embargo, si invierte la configuración useCapture en los dos controladores de eventos, el controlador de eventos hijo responde antes que el padre. La razón de esto es que el controlador de eventos hijo ahora se activará en la fase de captura que es anterior a la fase de burbujeo en la que se desencadenará el controlador de eventos principal.

Si configura useCapture como verdadero para ambos manejadores de eventos, independientemente del orden de definición, el controlador de eventos padre se activará primero porque se presenta antes que el niño en la fase de captura.

Por el contrario, si configura useCapture en false para ambos manejadores de eventos, nuevamente sin importar el orden de definición, el controlador de eventos hijo se activará primero porque viene antes que el padre en la fase de burbujeo.

Resumen:

La especificación DOM descrita en:

https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases

funciona de la siguiente manera:

Se envía un evento siguiendo una ruta desde la raíz ( document ) del árbol hasta el nodo de destino . El nodo objective es el elemento HTML más profundo, es decir, el evento.target. 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 objective desde la raíz del árbol ( document ) al padre directo del nodo objective.
  2. La fase objective: el evento se envía al nodo objective. La fase de destino siempre está en el elemento html más profundo en el que se disparó el evento.
  3. La fase de burbujeo: el evento se envía a los antepasados ​​del objective desde el padre directo del nodo de destino hasta la raíz del árbol.

Ebullición del evento, captura del evento, objetivo del evento

Ejemplo:

 // bubbling handlers, third argument (useCapture) false (default) document.getElementById('outerBubble').addEventListener('click', () => { console.log('outerBubble'); }, false) document.getElementById('innerBubble').addEventListener('click', () => { console.log('innerBubble'); }, false) // capturing handlers, third argument (useCapture) true document.getElementById('outerCapture').addEventListener('click', () => { console.log('outerCapture'); }, true) document.getElementById('innerCapture').addEventListener('click', () => { console.log('innerCapture'); }, true) 
 div:hover{ color: red; cursor: pointer; } 
  
click me to see Bubbling
click me to see Capturing