Mecanismo de propagación de eventos en JS

1. La difusión del evento

Después de que ocurra un evento en JavaScript, se propagará entre el elemento secundario y el elemento principal. Esta propagación se divide en tres etapas.

  • La primera fase : conducción desde el objeto de la ventana hasta el nodo de destino (capa superior a capa inferior), denominada " fase de captura ".
  • La segunda fase : desencadenada en el nodo objetivo, denominada " fase objetivo " (fase objetivo).
  • La tercera etapa : el objeto de la ventana se transmite desde el nodo de destino (desde la capa inferior a la capa superior), que se denomina " fase de burbujeo ".

Este modelo de propagación de tres etapas permite que se active el mismo evento en varios nodos.


Dos, demostración de código

<!--<div>节点之中有一个<p>节点。-->
<div>
  <p>点击</p>
</div>
/**
   * 如果对这两个节点,都设置click事件的监听函数
   * (每个节点的捕获阶段和冒泡阶段,各设置一个监听函数),
   * 共计设置四个监听函数。然后,对<p>点击,click事件会触发四次。
   * */
  var phases = {
    
    
    1: 'capture',
    2: 'target',
    3: 'bubble'
  };

  var div = document.querySelector('div');
  var p = document.querySelector('p');

  div.addEventListener('click', callback, true);
  p.addEventListener('click', callback, true);
  div.addEventListener('click', callback, false);
  p.addEventListener('click', callback, false);

  function callback(event) {
    
    
    var tag = event.currentTarget.tagName;
    var phase = phases[event.eventPhase];
    console.log("Tag: '" + tag + "'. EventPhase: '" + phase + "'");
  }
  
// 点击以后的结果
// Tag: 'DIV'. EventPhase: 'capture'
// Tag: 'P'. EventPhase: 'target'
// Tag: 'P'. EventPhase: 'target'
// Tag: 'DIV'. EventPhase: 'bubble'

1. Análisis de resultados

El código anterior indica que el evento de clic se activa cuatro veces: una vez en la fase de captura y la fase de burbujeo del nodo div, y dos veces en la fase objetivo del nodo p.

1. 捕获阶段:事件从div向p传播时,触发div的click事件;
2. 目标阶段:事件从div到达p时,触发p的click事件;
3. 冒泡阶段:事件从p传回div时,再次触发div的click事件。

Entre ellos, el nodo p tiene dos funciones de monitoreo (el tercer parámetro del método addEventListener es diferente, lo que hará que dos funciones de monitoreo estén vinculadas), por lo que todas se activarán una vez debido al evento de clic. Por lo tanto, p se emitirá dos veces en la fase objetivo.

事件传播的最上层对象是window,接着依次是document,html(document.documentElement)和body(document.body)。
也就是说,上例的事件传播顺序,在捕获阶段依次为window、document、html、body、div、p
在冒泡阶段依次为p、div、body、html、document、window

2 、 addEventListener ()

addEventListener () se usa para definir una función de escucha para un evento específico en el nodo u objeto actual. Una vez que ocurra este evento, se ejecutará la función de monitoreo. Este método no tiene valor de retorno.

target.addEventListener(type, listener[, useCapture]);

El método acepta tres parámetros.

  • tipo : nombre del evento, distingue entre mayúsculas y minúsculas.
  • oyente : función de oyente. Cuando ocurre un evento, se llamará a la función de escucha.
  • useCapture : valor booleano, que indica si la función de monitor se activa en la fase de captura (captura), el valor predeterminado es falso (la función de monitor solo se activa en la fase de burbujeo) . Este parámetro es opcional.

3 、 event.eventPhase

La propiedad event.eventPhase devuelve una constante entera que representa la fase actual del evento . Este atributo es de solo lectura.

Hay cuatro posibilidades para el valor de retorno de event.eventPhase.

  • 0: el evento no ha ocurrido actualmente.
  • 1: El evento se encuentra actualmente en la etapa de captura, es decir, en proceso de propagación desde el nodo ancestro al nodo de destino.
  • 2: el evento llega al nodo de destino, que es el nodo al que apunta la propiedad event.target.
  • 3: El evento está en la fase de burbujeo, es decir, en el proceso de retropropagación desde el nodo objetivo al nodo ancestro.

4 、 event.currentTarget 与 event.target

Después de que ocurra el evento, pasará por dos etapas de captura y propagación, pasando por múltiples nodos DOM a su vez. Por lo tanto, en cualquier momento, hay dos nodos relacionados con el evento, uno es el nodo desencadenante original del evento (event.target) y el otro es el nodo por el que pasa actualmente el evento (event.currentTarget). El primero suele ser un nodo descendiente del segundo.

La propiedad event.currentTarget devuelve el nodo donde se encuentra actualmente el evento, es decir, el nodo por el que está pasando el evento, es decir, el nodo donde se encuentra la función de supervisión que se está ejecutando actualmente . A medida que se propaga el evento, el valor de esta propiedad cambiará.

La propiedad event.target devuelve el nodo que desencadenó originalmente el evento, es decir, el nodo donde ocurrió originalmente el evento . Esta propiedad no cambiará a medida que se propague el evento.

Durante el proceso de propagación de eventos, los valores de las propiedades event.target y event.currentTarget en las funciones de monitoreo de diferentes nodos son diferentes.

// HTML 代码为
// <p id="para">Hello <em>World</em></p>
function hide(e) {
    
    
  // 不管点击 Hello 或 World,总是返回 true
  console.log(this === e.currentTarget);

  // 点击 Hello,返回 true
  // 点击 World,返回 false
  console.log(this === e.target);
}

document.getElementById('para').addEventListener('click', hide, false);

En el código anterior, em es un nodo hijo de p. Al hacer clic en em o p, se ejecutará la función de supervisión. En este momento, e.target siempre apunta al nodo en la posición de clic original, y e.currentTarget apunta al nodo que está pasando durante el proceso de propagación del evento.

Dado que la función de monitoreo se activa solo cuando pasa el evento, e.currentTarget siempre es equivalente a esto dentro de la función de monitoreo. esto apunta al elemento registrado por el controlador de eventos.


Tres, materiales de referencia

https://wangdoc.com/javascript/events/model.html
https://wangdoc.com/javascript/events/event.html#navbar
https://wangdoc.com/javascript/events/eventtarget.html#navbar

Supongo que te gusta

Origin blog.csdn.net/weixin_43974265/article/details/110531855
Recomendado
Clasificación