not español change javascript dom javascript-events dom-events

javascript - español - addeventlistener jquery



No se puede entender el parámetro useCapture en addEventListener (9)

Resumen:

La especificación de 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 de destino 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 destino desde la raíz del árbol ( document ) al padre directo del nodo de destino.
  2. La fase de destino: el evento se envía al nodo de destino. La fase de destino siempre está en el elemento html más profundo en el que se realizó el evento.
  3. La fase de propagación: el evento se envía a los ancestros del destino desde el padre directo del nodo de destino a la raíz del árbol.

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

<!-- event bubbling --> <div id="outerBubble"> <div id="innerBubble">click me to see Bubbling</div> </div> <!-- event capturing --> <div id="outerCapture"> <div id="innerCapture">click me to see Capturing</div> </div>

El ejemplo anterior realmente ilustra la diferencia entre la propagación de eventos y la captura de eventos. Al agregar los detectores de eventos con addEventListener , hay un tercer elemento llamado useCapture. Este es un valor boolean que, cuando se establece en true permite que el detector de eventos utilice la captura de eventos en lugar del burbujeo de eventos.

En nuestro ejemplo, cuando establecemos el argumento useCapture en false , vemos que se produce una burbuja de eventos. Primero se dispara el evento en la fase de destino (registros de InternalBubble), y luego, a través de la propagación de eventos, se desencadena el evento en el elemento principal (registros de outerBubble).

Cuando configuramos el argumento useCapture en true , vemos que el evento en el <div> externo se activa primero. Esto se debe a que el evento ahora se activa en la fase de captura y no en la fase de propagación.

He leído el artículo en https://developer.mozilla.org/en/DOM/element.addEventListener pero no useCapture entender el atributo useCapture . 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 EventTargets debajo del árbol DOM. Los eventos que burbujean hacia arriba a través del árbol no activarán un oyente designado para usar 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 del documento tiene usecapture true y el div del niño tiene usecapture establecido en false y se sigue la captura del documento del documento.

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>


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


Dadas las tres fases de viaje del evento:

  1. La fase de captura : el evento se envía a los ancestros del destino desde la raíz del árbol al padre directo del nodo de destino.
  2. La fase de destino : el evento se envía al nodo de destino.
  3. La fase de propagación : el evento se envía a los ancestros del destino desde el padre directo del nodo de destino a la raíz del árbol.

useCapture indica en qué fases se realizará el viaje del evento:

Si es true , useCapture indica que el usuario desea agregar el detector de eventos solo para la fase de captura, es decir, este detector de eventos no se activará durante las fases objetivo y de propagación. Si es false , el detector de eventos solo se activará durante las fases de destino y propagación

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


Ejemplo de código:

<div id="div1" style="background:#9595FF"> Outer Div<br /> <div id="div2" style="background:#FFFFFF"> Inner Div </div> </div>

Código Javascript:

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

si ambos están configurados en falso

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

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

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

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. Interna, las alertas se muestran como: Div 1> Div 2

Aquí el script se ejecuta desde el elemento ancestro / exterior: Captura de eventos (useCapture se ha establecido 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);

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

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

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. Interna, las alertas se muestran como: Div 1> Div 2

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


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

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

Si establece useCapture en true para ambos controladores de eventos, independientemente del orden de definición, el controlador de eventos padre se activará primero porque se presenta antes que el hijo en la fase de captura.

A la inversa, si configura useCapture en falso para ambos controladores de eventos (nuevamente, independientemente del orden de definición), el controlador de eventos hijo se activará primero porque va antes que el padre en la fase de propagación.


Evento de captura vs evento de burbuja

  • El evento de captura se enviará antes del evento de burbuja
  • El orden de propagación del evento es
    1. Captura de 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 | | | | ---------------------------- | | | --------------------------------------

Demo

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

<div id="parent"> <button id="child">Click</button> </div>


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. Diga, usted define 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);

Los cuadros de alerta aparecerán en este orden:

  • 2 (definido primero, usando capture=true )
  • 4 (segundo definido usando capture=true )
  • 1 (primer evento definido con capture=false )
  • 3 (segundo evento definido con capture=false )

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

Abajo, contenido extraído del enlace.

Fases

El evento se distribuye siguiendo una ruta desde la raíz del árbol a este nodo de destino. Entonces puede manejarse localmente en el nivel del nodo de destino o desde los ancestros de cualquier objetivo en la parte superior del á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 ancestros del destino desde la raíz del árbol al padre directo del nodo de destino.
  2. La fase de destino: el evento se envía al nodo de destino.
  3. La fase de propagación: el evento se envía a los ancestros del destino desde el padre directo del nodo de destino a la raíz del árbol.

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

Algunos eventos pueden no necesariamente cumplir 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 lograrán las fases de captura y destino, pero algunos no lograrán la fase de propagación ("eventos de propagación" en lugar de "eventos de no propagación", consulte también el atributo Event.bubbles).