¿Qué es la difusión y captura de eventos?
¿Cuál es la diferencia entre la difusión y captura de eventos? ¿Cuándo se debe utilizar burbujeo frente a captura?
La propagación y captura de eventos son dos formas de propagación de eventos en la API HTML DOM, cuando un evento ocurre en un elemento dentro de otro elemento y ambos elementos han registrado un identificador para ese evento. El modo de propagación de eventos determina en qué orden los elementos reciben el evento .
Con la burbujeación, el evento primero es capturado y manejado por el elemento más interno y luego propagado a los elementos externos.
Con la captura, el evento es capturado primero por el elemento más externo y se propaga a los elementos internos.
La captura también se llama "goteo", lo que ayuda a recordar el orden de propagación:
gotear, burbujear
En los viejos tiempos, Netscape defendía la captura de eventos, mientras que Microsoft promovía la difusión de eventos. Ambos son parte del estándar W3C Document Object Model Events (2000).
IE < 9 utiliza únicamente la propagación de eventos , mientras que IE9+ y todos los principales navegadores admiten ambos. Por otro lado, el rendimiento de la propagación de eventos puede ser ligeramente inferior para DOM complejos.
Podemos usar addEventListener(type, listener, useCapture)
para registrar controladores de eventos en modo burbujeo (predeterminado) o captura. Para utilizar el modelo de captura, pase el tercer argumento como true
.
Ejemplo
<div>
<ul>
<li></li>
</ul>
</div>
En la estructura anterior, supongamos que se produjo un evento de clic en el li
elemento.
En el modelo de captura, el evento será manejado por el div
primero (haga clic en los controladores de eventos en el div
elemento de destino, se activará primero), luego en ul
y luego en el último elemento de destino li
.
En el modelo burbujeante sucederá lo contrario: el evento será manejado primero por el li
, luego por el ul
y finalmente por el div
elemento.
Para más información, ver
- Orden de eventos en QuirksMode
- agregarEventListener en MDN
- Eventos avanzados en QuirksMode
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 difusió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());
}
function clearOutput() {
logElement.innerHTML = "";
}
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);
}
var clearButton = document.getElementById('clear');
clearButton.addEventListener('click', clearOutput);
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 id="clear">clear output</button>
<section id="log"></section>
Otro ejemplo en JSFiddle .
Descripción:
quirksmode.org tiene una buena descripción de esto. En pocas palabras (copiado de quirksmode):
captura de eventos
Cuando usas la captura de eventos
| | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 \ / | | | ------------------------- | | Event CAPTURING | -----------------------------------
el controlador de eventos del elemento1 se activa primero, el controlador de eventos del elemento2 se activa al final.
Evento burbujeante
Cuando usas la difusión de eventos
/ \ ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | -----------------------------------
el controlador de eventos del elemento2 se activa primero, el controlador de eventos del elemento1 se activa al final.
¿Qué usar?
Depende de lo que quieras hacer. No hay nada mejor. La diferencia es el orden de ejecución de los controladores de eventos. La mayoría de las veces estará bien activar los controladores de eventos en la fase de burbujeo , pero también puede ser necesario activarlos antes.