¿Qué es la difusión y captura de eventos?

Resuelto Arun P Johny asked hace 13 años • 11 respuestas

¿Cuál es la diferencia entre la difusión y captura de eventos? ¿Cuándo se debe utilizar burbujeo frente a captura?

Arun P Johny avatar Jan 06 '11 22:01 Arun P Johny
Aceptado

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 lielemento.

En el modelo de captura, el evento será manejado por el divprimero (haga clic en los controladores de eventos en el divelemento de destino, se activará primero), luego en uly 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 uly finalmente por el divelemento.

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>
Expandir fragmento

Otro ejemplo en JSFiddle .

Arun P Johny avatar Jan 06 '2011 15:01 Arun P Johny

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.

Felix Kling avatar Jan 06 '2011 15:01 Felix Kling