Event propagation mechanism in JS

1. The spread of the event

After an event occurs in JavaScript, it will propagate between the child element and the parent element. This spread is divided into three stages.

  • The first phase : conduction from the window object to the target node (from the upper layer to the bottom layer), called the " capture phase ".
  • The second phase : triggered on the target node, called the " target phase " (target phase).
  • The third stage : the window object is transmitted back from the target node (from the bottom layer to the upper layer), which is called the " bubbling phase ".

This three-stage propagation model enables the same event to be triggered on multiple nodes.


Two, code demonstration

<!--<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. Result analysis

The above code indicates that the click event is triggered four times: once in the capture phase and bubbling phase of the div node, and twice in the target phase of the p node.

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

Among them, the p node has two monitoring functions (the third parameter of the addEventListener method is different, which will cause two monitoring functions to be bound), so they will all be triggered once because of the click event. Therefore, p will be output twice in the target phase.

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

2、addEventListener()

addEventListener() is used to define a listener function for a specific event on the current node or object. Once this event occurs, the monitoring function will be executed. This method has no return value.

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

The method accepts three parameters.

  • type : Event name, case sensitive.
  • listener : listener function. When an event occurs, the listener function will be called.
  • useCapture : Boolean value, indicating whether the monitor function is triggered in the capture phase (capture), the default is false (the monitor function is only triggered in the bubbling phase) . This parameter is optional.

3、event.eventPhase

The event.eventPhase property returns an integer constant that represents the current phase of the event . This attribute is read-only.

There are four possibilities for the return value of event.eventPhase.

  • 0: The event has not occurred currently.
  • 1: The event is currently in the capture stage, that is, in the process of propagation from the ancestor node to the target node.
  • 2: The event reaches the target node, which is the node pointed to by the event.target property.
  • 3: The event is in the bubbling phase, that is, in the process of back propagation from the target node to the ancestor node.

4、event.currentTarget与event.target

After the event occurs, it will go through two stages of capture and bubbling, passing through multiple DOM nodes in turn. Therefore, at any point in time, there are two nodes related to the event, one is the original trigger node of the event (event.target), and the other is the node that the event is currently passing through (event.currentTarget). The former is usually a descendant node of the latter.

The event.currentTarget property returns the node where the event is currently located, that is, the node that the event is currently passing through, that is, the node where the currently executing monitoring function is located . As the event propagates, the value of this property will change.

The event.target property returns the node that originally triggered the event, that is, the node where the event originally occurred . This property will not change as the event propagates.

During the event propagation process, the values ​​of the event.target and event.currentTarget properties in the monitoring functions of different nodes are different.

// 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);

In the above code, em is a child node of p. Clicking em or p will cause the monitoring function to execute. At this time, e.target always points to the node at the original click position, and e.currentTarget points to the node that is passing during the event propagation process.

Since the monitoring function is triggered only when the event passes, e.currentTarget is always equivalent to this inside the monitoring function. this points to the element registered by the event handler!


Three, reference materials

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

Guess you like

Origin blog.csdn.net/weixin_43974265/article/details/110531855