Event target lookup method, event proxy, the difference between e.target and e.currentTarget, prevent bubbling and capture, cancel the default event once to understand, just read this

EventTarget Finding method of event target (bubbling and capture)

Bubbling and capture:
  • Bubbling event
    • The event defaults to a bottom-up bubbling execution method. Take the click event as an example. When we click on the child element, the click event of the parent element and above can also be triggered. The order of execution of events is from bottom to top, which is a bubbling event.
  • Capture event:
    • Of course, there is also a top-down capture method. Take the click event as an example. When a child element is bound to a click event, when we click on the child element, the click event bound to the parent element and the above elements will also be executed. The execution sequence of events is from top to bottom, which is the capture event.
addEventListener(type,listener,useCapture) Simple analysis:
  • type: Event type
  • listener: event listener processing function
  • useCapture: Set the event search method
    • false, bubbling event (default value)
    • true, capture event
Detailed explanation of parameter useCapture:

The value of useCapture determines whether the search method of the event target is capture or bubbling.

When an element is nested with another element, and both elements are registered for the same event. Set different useCapture values ​​(bubbling and capture) for two elements, so bubbling and capture are two different event lookup methods. The event lookup method determines the order in which the elements receive events.

The sequence of bubbling and capturing:

Insert picture description here

  • It can be seen from the figure that the event is captured first and then event bubbling. Event capture is from top to bottom, and event bubbling is from bottom to top.
  • The process of capturing is from unspecific to specific, and bubbling is from specific to unspecific.
  • Although it isCapture first, But the bubbling event is the default way of delivery.
Code demo:
<body>
    <div id="div1">
        这是div1
        <div id="div2">
            这是div2
            <div id="div3">这是div3</div>
        </div>
    </div>
    <script>
        let div1 = document.getElementById('div1');
        let div2 = document.getElementById('div2');
        let div3 = document.getElementById('div3');
        div1.addEventListener('click',function(){
     
     
            console.log("这是div1的点击事件");
        },false);
        div2.addEventListener('click',function(){
     
     
            console.log("这是div2的点击事件");
        },false);
        div3.addEventListener('click',function(){
     
     
            console.log("这是div3的点击事件");
        },false);
    </script>
</body>

When we click on div3, as can be seen from the console results as follows, what happened here is a bubbling event.
Insert picture description here
Still click div3, we change the div1.addEventListenerthird parameter to true, as you can see as follows, div1 is executed first, indicating that capture takes precedence over bubbling.
Insert picture description here

The above are the two mechanisms I use to find event targetsbubbleversuscaptureunderstanding.

Event proxy mechanism

Use event bubbling to complete the event proxy mechanism:
<ul>
    <li>列表1</li>
    <li>列表2</li>
</ul>

When we want to libind a click event to all the items in the above list, click to get the data in li, we usually use for to traverse the element to bind the click event.

let lis = document.querySelectorAll('li');
for (let i = 0; i < lis.length; i++) {
    
    
	lis[i].addEventListener('click', function () {
    
    
 		console.log(this.innerHTML);
	});
}

But when we have too many elements, this operation will affect the code performance, so we can use the bubbling mechanism to complete the event proxy. Is to bind the event to the parent element.

Knowledge points about event objects:
  • When we EventTarget.addEventListener(type,listener,useCapture);bind an event, the first parameter in the event listener processing function (listener) isEvent object. The event object contains detailed information about the event, such as the event source, event id, event type, event binding element, and the click location when the event is triggered.
<body>
    <ul>
        <li>列表1</li>
        <li>列表2</li>
    </ul>
    <script>
        let ul = document.querySelector('ul');
        //我们可以通过事件对象e中的target属性可以访问到事件源(也就事件的触发元素)
        ul.addEventListener('click',function(e){
     
     
            console.log(e.target.innerHTML);
        },false);
    </script>
</body>

Click List 1 and List 2:
Insert picture description here
Summary: Through the above code, we know that e.target can implement event delegation. Event delegation is to add events to the parent element through event bubbling (or event capture), and e.target can access triggers. The element of the event (event source). So e.target is the starting point of bubbling, and e.target is the end of capture.

The difference between e.target and e.currentTarget:

  • e.target points to the object (event source) that triggers the event listener.
  • e.currentTarget points to the object that listens to the event (the dom element to which the event is bound).

Prevent bubbling and capture

Why stop bubbling or capturing?

(I will leave out the event proxy here for the time being.) When the current element is clicked, the event is delivered in a bubbling way. If the parent element is bound to the same event, it will be triggered by the bubbling delivery. In the same capture process, the parent of the same event bound to the current element will also be triggered. Only the trigger sequence is different.

Event agents generally use bubbling. Of course, preventing bubbling will generally not affect event agents, because sequence problems will only affect the capture of events, which is why bubbling is used to implement event agent mechanisms.

Ways to prevent bubbling or capture

I do not consider compatibility issues here, I believe that compatibility can be resolved in the near future.

The method to stop the bubbling w3c recommendation is event.stopPropagation(), as the name implies, stop the propagation, it is the method of the event object (event), this method isPrevent the target element from bubbling (or capturing)

event.stopPropagation() prevents bubbling:
<body>
    <div id="div1">
        这是div1
        <div id="div2">
            这是div2
            <div id="div3">这是div3</div>
        </div>
    </div>
    <script>
        let div1 = document.getElementById('div1');
        let div2 = document.getElementById('div2');
        let div3 = document.getElementById('div3');
        div1.onclick = function (e) {
     
     
           alert('div1');
        }
        div2.onclick = function (e) {
     
     
           e.stopPropagation();
            alert('div2');
        }
        div3.onclick = function (e) {
     
     
           alert('div3');
        }
    </script>
</body>

The above codes are all bubbling events by default. When we click on div3,'div3' and'div2' will pop up in turn. Why doesn't'div1' pop up? This is because e.stopPropagation(); prevents the event of the target element from continuing to bubble to the upper level. If e.topPropagation is added to each click event, there will be no multiple pop-ups.

event.stopPropagation() prevents capture:
<body>
    <div id="div1">
        这是div1
        <div id="div2">
            这是div2
            <div id="div3">这是div3</div>
        </div>
    </div>
    <script>
        let div1 = document.getElementById('div1');
        let div2 = document.getElementById('div2');
        let div3 = document.getElementById('div3');
        div1.addEventListener('click',function(e){
     
     
           	console.log('div1');
        },true);
        div2.addEventListener('click',function(e){
     
     
            console.log('div2');
            e.stopPropagation();
        },true);
        div3.addEventListener('click',function(e){
     
     
            console.log('div3');
        },true);
    </script>
</body>

When we click on div2,'div1' and'div2' will pop up in turn. This is also because we set e.stopPropagation() in the div2 event, and the event that blocked the target element continues to be captured.

event.target == event.currentTarget:
div.addEventListener('click',function(e){
    
    
	if(event.target == event.currentTarget){
    
    
        //需要执行的代码
    }
});

This method does not require much explanation. If you understand the above content, this method can also be understood.

Why useaddEventListener()

It is not difficult to see from the above code that addEventListener()there are the following advantages (the following are the original words of MDN ):

addEventListener()It is a method for registering event listeners provided in the W3C DOM specification. Its advantages include:

  • It allows multiple listeners to be registered for an event. Especially when using AJAX libraries, JavaScript modules, or other codes that require third-party libraries/plugins.
  • It provides a more sophisticated means to control the listenertrigger stage. (That is, you can choose to capture or bubble).
  • It is valid for any DOM element, not just for HTML elements.

Cancel the default event

event.preventDefault()

The default event refers to a label with a default behavior <a href="">, <input type="submit">such as a label, which can be jumped or submitted by clicking. We bind a click event to this type of label, and set the preventDefault() method of the event object to prevent the default event from occurring.

<body>
   <a href="https://www.baidu.com">点击跳转</a>
    <script>
        let a = document.querySelector('a');
        addEventListener('click',function(e){
     
     
            e.preventDefault();
        })
    </script>
</body>

So how can we know whether a label has a default event, print the cancelable property of the event object, and know the result of e.cancelable through event execution, if it is false, it means there is a default event, and true is not.

return false;

Set in the event execution functionreturn falseCancel the default event, but this method is not commonly used.

希望大家能关注我的公众号,我会继续分享更多前端实用技术
Insert picture description here

Guess you like

Origin blog.csdn.net/m0_46217225/article/details/115328572