Directorio de artículos
Flujo de eventos DOM
Para entender el flujo de eventos, primero debemos entender tres cosas:
- Los elementos no son independientes, están concatenados.
- Cuando un solo elemento desencadena un evento, afectará a otros elementos
- La forma de flujo de eventos: captura de eventos (propuesta de Netscape), burbujeo de eventos (propuesta de IE)
Tomemos la imagen de arriba como ejemplo. Suponga que vincula un evento de clic al div. Cuando hace clic en el div, otros elementos también se verán afectados, lo que provocará el efecto de afectar todo el cuerpo .
Hay dos formas de flujo de eventos: 事件冒泡
,事件捕获
evento burbujeante
Etapa de burbujeo del evento: active el evento de destino inmediatamente después de hacer clic en el div y luego burbujee capa por capa
captura de eventos
Etapa de captura de eventos: después de hacer clic en el div, el evento del div no se activará inmediatamente , sino que se capturará capa por capa, y el evento se activará cuando finalmente se alcance el div.
De hecho, estas dos etapas pueden encontrarse en el desarrollo de proyectos futuros, porque diferentes métodos de eventos vinculantes crean diferentes etapas de eventos (burbujeo/captura)
Escenario 1: enlazar eventos directamente en HTML
<body onclick="console.log('我是body')">
<button onclick="console.log('我是button')">
<span onclick="console.log('我是span')">快乐按钮</span>
</button>
</body>
Efecto:
como se puede ver en la figura anterior, cuando hacemos clic en la etiqueta de intervalo, los eventos en el botón superior y los eventos en el cuerpo se ejecutarán en el orden de burbujeo
Escenario 2: método [domNode].onclick() - nivel DOM0
html:
<body>
<button>
<span>快乐按钮</span>
</button>
</body>
JavaScript:
var body = document.getElementsByTagName('body')[0];
var button = document.getElementsByTagName('button')[0];
var span = document.getElementsByTagName('span')[0];
body.onclick = function() {
console.log('我是body')};
button.onclick = function() {
console.log('我是button')};
span.onclick = function() {
console.log('我是span')};
Efecto:
Descubrimos que la forma de vincular eventos en el nivel DOM0 todavía está en forma de burbujeo
Escenario 3: método [domNode].addEventListener() - nivel DOM2
añadirEvenListener(
事件名
,事件触发后的回调
,布尔值
)
falso (predeterminado): indica que el controlador de eventos se invoca durante la fase de propagación
verdadero: indica que el controlador de eventos se invoca durante la fase de captura
html:
<body>
<button>
<span>快乐按钮</span>
</button>
</body>
JavaScript:
var body = document.getElementsByTagName('body')[0];
var button = document.getElementsByTagName('button')[0];
var span = document.getElementsByTagName('span')[0];
function theName() {
console.log('我是' + this.nodeName)};
body.addEventListener('click',theName,false);
button.addEventListener('click',theName,false);
span.addEventListener('click',theName,false);
Efecto:
podemos ver que cuando el tercer parámetro de addEventListener es falso (el valor predeterminado es falso si no está escrito), el flujo de eventos está burbujeando.
Cuando cambiamos el tercer parámetro a verdadero:
......
body.addEventListener('click',theName,true);
button.addEventListener('click',theName,true);
span.addEventListener('click',theName,true);
Descubrimos que el orden de ejecución es cuerpo --> botón --> intervalo, que es la fase de captura de eventos.
Regulaciones DOM nivel 2:
- El flujo de eventos consta de tres etapas (1. Etapa de captura 2. Etapa de destino 3. Etapa de burbujeo)
执行循序
Se debe seguir: Fase de captura -> Fase objetivo -> Fase de burbuja
Es decir, al hacer clic en el elemento de destino, el evento desencadenante no se ejecutará inmediatamente, sino que se ejecutará primero la fase de captura del evento -> luego en la fase objetivo (evento desencadenante) -> fase de burbujeo del evento
Echemos un vistazo a una pregunta de entrevista clásica: ¿Cuál es el orden de salida cuando hacemos clic en bebé?
html:
<body>
<div class="grandma">grandma奶奶
<div class="mother">mother妈妈
<div class="daughter">daughter
<div class="baby">baby婴儿</div>
</div>
</div>
</div>
</body>
javascript:
var grandma = document.getElementsByClassName('grandma')[0]
var mother = document.getElementsByClassName('mother')[0]
var daughter = document.getElementsByClassName('daughter')[0]
var baby = document.getElementsByClassName('baby')[0]
function theName() {
console.log('我是' + this.className);
}
baby.addEventListener('click', theName, false)//冒泡
daughter.addEventListener('click', theName, true)//捕获
mother.addEventListener('click', theName, true)//捕获
grandma.onclick = theName//冒泡
Resultado: La
idea de hacer la pregunta:
- Primero dividir los elementos que unen el evento a capturar? ¿burbuja? podemos ver
daughter
ymother
para捕获
;baby
ygrandma
para冒泡
- Debido a que DOM2 estipula que la primera captura y luego el burbujeo , por lo que uno de la hija y la madre se imprimirá primero.
- Debido a que la captura es de arriba a abajo (raíz dom -> div), primero imprima madre y luego hija
- Debido a que el burbujeo es de abajo hacia arriba (raíz div->dom), imprima bebé y luego imprima abuela