What is the event delegation in JS?

Reference: JavaScript event delegation and event delegation

1. Definition

Event delegation is to use the event bubbling mechanism, only specify an event handler, you can manage all events of a certain category

2. Why use event delegation?

After adding event handlers to the DOM, you need to constantly interact with DOM nodes. The more times you visit the DOM, the more times the browser will reflow and redraw. If you use event delegation, you can put all operations into the js program, and you only need to interact with the DOM once, which can greatly reduce the number of interactions with the DOM and improve performance

3. DOM2 level event

  1. Event capture : When an element triggers an event (such as onclick), the top-level object document will emit an event stream, which will flow to the target element node along with the DOM tree node until it reaches the target element where the event actually occurred. In this process, the listener function corresponding to the event will not be triggered
  2. Event target : After reaching the target element, execute the corresponding processing function of the event of the target element. If the listener function is not bound, it will not be executed
  3. Event bubbling : Start from the target element and spread to the top element. If there are nodes bound to corresponding event handling functions on the way, these functions will all be triggered once. If you want to prevent the event from bubbling, you can use e.stopPropagation() (Firefox) or e.cancelBubble=true (IE) to prevent the event’s bubbling propagation

4. How to implement event delegation?

(1) When the li operation is the same effect
<ul id="ul1">
    <li>111</li>
    <li>222</li>
    <li>333</li>
    <li>444</li>
</ul>

No event delegation:

window.onload = function(){
    var oUl = document.getElementById("ul1");
    var aLi = oUl.getElementsByTagName('li');
    for(var i=0;i<aLi.length;i++){
        aLi[i].onclick = function(){
            alert(123);
        }
    }
}

There are event delegation:

window.onload = function(){
    var oUl = document.getElementById("ul1");
   oUl.onclick = function(){
        alert(123);
    }
}

Use the parent ul as the event proxy. When li is clicked, the event will be bubbled to ul due to the bubbling principle. Because there is a click event on the ul, the event will be triggered. Note that clicking ul at this time will also trigger. How to realize that only click li will trigger?
The Event object provides a property called target, which can return the target node of the event, which we call the event source.

window.onload = function(){
  var oUl = document.getElementById("ul1");
  oUl.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == 'li'){
            alert(123);
         alert(target.innerHTML);
    }
  }
}
(2) When the li operation effect is different
<div id="box">
        <input type="button" id="add" value="添加" />
        <input type="button" id="remove" value="删除" />
        <input type="button" id="move" value="移动" />
        <input type="button" id="select" value="选择" />
 </div>
window.onload = function(){
            var oBox = document.getElementById("box");
            oBox.onclick = function (ev) {
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == 'input'){
                    switch(target.id){
                        case 'add' :
                            alert('添加');
                            break;
                        case 'remove' :
                            alert('删除');
                            break;
                        case 'move' :
                            alert('移动');
                            break;
                        case 'select' :
                            alert('选择');
                            break;
                    }
                }
            }    
        }
(3) If it is a new node, will there be an event?

Bind events to each li node. When the event delegation mechanism is not used, the newly added li has no events.
No event delegation:

<input type="button" name="" id="btn" value="添加" />
<ul id="ul1">
        <li>111</li>
        <li>222</li>
        <li>333</li>
        <li>444</li>
</ul>
window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName('li');
            var num = 4;
            
            //鼠标移入变红,移出变白
            for(var i=0; i<aLi.length;i++){
                aLi[i].onmouseover = function(){
                    this.style.background = 'red';
                };
                aLi[i].onmouseout = function(){
                    this.style.background = '#fff';
                }
            }
            //添加新节点
            oBtn.onclick = function(){
                num++;
                var oLi = document.createElement('li');
                oLi.innerHTML = 111*num;
                oUl.appendChild(oLi);
            };
        }

There are event delegation:

window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName('li');
            var num = 4;
            
            //事件委托,添加的子元素也有事件
            oUl.onmouseover = function(ev){
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == 'li'){
                    target.style.background = "red";
                }
                
            };
            oUl.onmouseout = function(ev){
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == 'li'){
                    target.style.background = "#fff";
                }
                
            };
            //添加新节点
            oBtn.onclick = function(){
                num++;
                var oLi = document.createElement('li');
                oLi.innerHTML = 111*num;
                oUl.appendChild(oLi);
            };
        }

When using event delegation, there is no need to traverse the child nodes of the element, and the newly added child elements also have event effects.

Note: Inside the event handler, the object this is always equal to the value of currentTarget, and target only contains the actual target of the event

document.body.onclick = function(event) {
      alert(event.currentTarget === document.body);  // true
      alert(event.this === document.body);  // true
      alert(event.target === document.getElementById("myBtn"))  //true
    }

Both this and currentTarget are equal to document.body, because the event is registered to this element, but the target element is equal to the button element, because it is the real target of the click event.

Guess you like

Origin blog.csdn.net/weixin_43912756/article/details/108323533