Não é possível entender o parâmetro useCapture em addEventListener

Eu li o artigo em https://developer.mozilla.org/en/DOM/element.addEventListener mas não consegui entender o atributo useCapture . Definição existe:

Se for verdade, useCapture indica que o usuário deseja iniciar a captura. Após iniciar a captura, todos os events do tipo especificado serão despachados para o listener registrado antes de serem despachados para qualquer EventTargets abaixo dele na tree DOM. Os events que estão subindo pela tree não acionarão um ouvinte designado para usar a captura.

Nesse código, o evento pai é acionado antes do filho, portanto, não consigo entender seu comportamento. O object Document usecapture true e child div tem usecapture definido como false e o documento usecapture é seguido. Por isso, a propriedade do documento é preferida ao filho.

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

Os events podem ser ativados em duas ocasiões: no início (“captura”) e no final (“bolha”). Os events são executados na ordem em que estão definidos. Diga, você define 4 ouvintes de evento:

 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); 

Acho que esse diagrama é muito útil para entender as fases de captura / destino / bolha: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases

Abaixo, o conteúdo extraído do link.

Fases

O evento é despachado seguindo um caminho da raiz da tree para esse nó de destino. Em seguida, ele pode ser tratado localmente no nível do nó de destino ou dos ancestrais de qualquer alvo mais altos na tree. O despacho de events (também chamado de propagação de events) ocorre em três fases e na seguinte ordem:

  1. A fase de captura: o evento é enviado aos ancestrais do destino da raiz da tree para o pai direto do nó de destino.
  2. A fase de destino: o evento é enviado para o nó de destino.
  3. A fase de bubbling: o evento é enviado aos ancestrais do destino do pai direto do nó de destino para a raiz da tree.

representação gráfica de um evento despachado em uma árvore DOM usando o fluxo de evento DOM

Os antepassados ​​do alvo são determinados antes do despacho inicial do evento. Se o nó de destino for removido durante o despacho, ou se o ancestral de um destino for adicionado ou removido, a propagação do evento sempre será baseada no nó de destino e nos ancestrais do destino determinados antes do despacho.

Alguns events podem não necessariamente cumprir as três fases do stream de events do DOM, por exemplo, o evento só pode ser definido para uma ou duas fases. Como exemplo, os events definidos nesta especificação sempre realizarão as fases de captura e destino, mas alguns não realizarão a fase de bubbling (“bubbling events” versus “non-bubbling events”, veja também o atributo Event.bubbles).

Evento de Captura vs Evento de Bolha

  • Evento de Captura será enviado antes do Evento de Bolha
  • A ordem de propagação de events é
    1. Captura Parental
    2. Captura de crianças
    3. Bolha das crianças
    4. Bolha dos Pais

( stopPropagation() irá parar o stream)

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

Demonstração

 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); 
 

Quando você diz useCapture = true, os events são executados de cima para baixo na fase de captura, quando false, faz uma bolha de baixo para cima.

Exemplo de código:

 
Outer Div
Inner Div

Código Javascript:

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

se ambos estiverem definidos como falsos

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

Executa: Onclicking Inner Div, os alertas são exibidos como: Div 2> Div 1

Aqui o script é executado a partir do elemento interno: Event Bubbling (useCapture foi definido como false)

div 1 é definido como verdadeiro e div 2 é definido como falso

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

Executa: Onclicking Inner Div, os alertas são exibidos como: Div 1> Div 2

Aqui, o script é executado a partir do elemento ancestral / outer: Event Capturing (useCapture foi definido como true)

div 1 é definido como falso e div 2 é definido como verdadeiro

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

Executa: Onclicking Inner Div, os alertas são exibidos como: Div 2> Div 1

Aqui o script é executado a partir do elemento interno: Event Bubbling (useCapture foi definido como false)

div 1 é definido como true e div 2 é definido como true

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

Executa: Onclicking Inner Div, os alertas são exibidos como: Div 1> Div 2

Aqui, o script é executado a partir do elemento ancestral / outer: Captura de events, pois useCapture foi definido como true

É tudo sobre modelos de events: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow Você pode capturar events na fase de bubbling ou na fase de captura. Sua escolha.
Dê uma olhada em http://www.quirksmode.org/js/events_order.html – você achará muito útil.

Dadas as três fases da viagem do evento:

  1. A fase de captura : o evento é enviado aos ancestrais do destino da raiz da tree para o pai direto do nó de destino.
  2. A fase de destino : o evento é enviado para o nó de destino.
  3. A fase de bubbling : o evento é enviado aos ancestrais do destino do pai direto do nó de destino para a raiz da tree.

useCapture indica em quais fases a viagem do evento será useCapture :

Se true , useCapture indica que o usuário deseja include o ouvinte de evento apenas na fase de captura, ou seja, esse ouvinte de evento não será acionado durante as fases de destino e bubbling. Se for false , o ouvinte de evento será acionado apenas durante as fases de destino e bubbling

A origem é igual à segunda melhor resposta: https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases

A ordem de definição só importa se os itens estiverem no mesmo nível. Se você inverter a ordem de definição em seu código, obterá os mesmos resultados.

No entanto, se você inverter a configuração useCapture nos dois manipuladores de events, o manipulador de events filho responderá antes do pai. A razão para isso é que o manipulador de evento filho agora será acionado na fase de captura, que é anterior à fase de bubbling, na qual o manipulador de events pai será acionado.

Se você definir useCapture como true para ambos os manipuladores de events – independentemente da ordem de definição – o manipulador de events pai será acionado primeiro porque vem antes do filho na fase de captura.

Por outro lado, se você definir useCapture como false para ambos os manipuladores de events – novamente, independentemente da ordem de definição – o manipulador de evento filho será acionado primeiro, porque ele vem antes do pai na fase de bubbling.

Resumo:

A especificação do DOM descrita em:

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

funciona da seguinte maneira:

Um evento é despachado seguindo um caminho da raiz ( document ) da tree para o nó de destino . O nó de destino é o elemento HTML mais profundo, isto é, o event.target. O despacho de events (também chamado de propagação de events) ocorre em três fases e na seguinte ordem:

  1. A fase de captura: o evento é enviado aos ancestrais do destino da raiz da tree ( document ) para o pai direto do nó de destino.
  2. A fase de destino: o evento é enviado para o nó de destino. A fase de destino está sempre no elemento html mais profundo no qual o evento foi enviado.
  3. A fase de bubbling: o evento é enviado aos ancestrais do destino do pai direto do nó de destino para a raiz da tree.

Borbulhamento de evento, captura de evento, meta de evento

Exemplo:

 // 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