Explicación detallada del flujo de eventos de JavaScript


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)
    inserte la descripción de la imagen aquí

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

inserte la descripción de la imagen aquí
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

inserte la descripción de la imagen aquí
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:
Por favor agregue la descripción de la imagen
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:
Por favor agregue la descripción de la imagen
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:
Por favor agregue la descripción de la imagen
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);

Por favor agregue la descripción de la imagen
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é?
inserte la descripción de la imagen aquí
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
inserte la descripción de la imagen aquí
idea de hacer la pregunta:

  1. Primero dividir los elementos que unen el evento a capturar? ¿burbuja? podemos ver daughtery motherpara 捕获; babyy grandmapara冒泡
  2. 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.
  3. Debido a que la captura es de arriba a abajo (raíz dom -> div), primero imprima madre y luego hija
  4. Debido a que el burbujeo es de abajo hacia arriba (raíz div->dom), imprima bebé y luego imprima abuela

Supongo que te gusta

Origin blog.csdn.net/weixin_60297362/article/details/123314010
Recomendado
Clasificación