【JavaScript】事件委托

165 阅读3分钟

什么是事件委托

事件委托又叫事件代理,它将元素的事件绑定到父级或更外层元素上,真正绑定事件的外层的元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上。

  • 那什么是事件冒泡呢?

事件冒泡:是"事件流"一个阶段,指事件开始由最具体的元素接收,然后逐步向上传播到较为不具体的节点或文档。

事件流:

R-C.png

  • 举个例子:

一个班的同学快递同时到了,一种方法就是他们都傻傻地一个个去领取,还有一种方法就是把这件事情委托给班长,让一个人出去拿所有快递,然后再根据收件人一一分发给每个同学。

这里取快递就是一个事件,每个同学指的是需要响应事件的 DOM 元素,而出去统一领取快递的宿舍长就是代理的元素。

为什么要用事件委托

  • 减少内存消耗

举个栗子八:有100个li,我们去给这100个li绑定click事件,那么我们就需要去操作dom100次,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间。而如果要用事件委托,就会将所有的li绑定的事件,绑定到ul上,则与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能。

  • 动态绑定事件 在很多时候,我们需要通过 AJAX 或者用户操作动态的增加或者去除列表项元素,那么在每一次改变的时候都需要重新给新增的元素绑定事件,给即将删去的元素解绑事件。而使用事件委托,因为事件是绑定在父层的,执行到目标元素时,可通过事件冒泡去匹配该事件。

实现

  • 相同效果
<ul id="ul1">
    <li>111</li>
    <li>222</li>
    <li>333</li>
    <li>444</li>
</ul>

将li的点击事件绑定到ul,当点击ul时,也会触发这个点击事件,下面代码就解决了,只有点击li时,才会触发点击事件,点击ul没有效果。

window.onload = function(){
  var oUl = document.getElementById("ul1");
  oUl.onclick = function(ev){      
    var ev = ev || window.event; // 兼容
    var target = ev.target || ev.srcElement;
            // Event对象提供了一个属性叫target,可以返回事件的目标节点,
            但有兼容性,标准浏览器用ev.target,IE浏览器用event.srcElement
    if(target.nodeName.toLowerCase() == 'li'){
         alert(123);
         alert(target.innerHTML);
    }
  }
}
  • 不同效果
<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.toLocaleLowerCase() == 'input'){
                    switch(target.id){
                        case 'add' :
                            alert('添加');
                            break;
                        case 'remove' :
                            alert('删除');
                            break;
                        case 'move' :
                            alert('移动');
                            break;
                        case 'select' :
                            alert('选择');
                            break;
                    }
                }
            }
            
        }

总结

1.适合用事件委托的事件:click、mousedown、mouseup、keydown、keyup、keypress 2.mouseover和mouseout虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。 3.不适合的就有很多,举个例子,mousemove,每次都要计算它的位置,非常不好把控,再比如focus,blur之类的,本身就没用冒泡的特性,自然就不能用事件委托了。

最后,这只时自己学习时的笔记,有不对的地方,欢迎指正 参考文献:www.cnblogs.com/liugang-vip…
juejin.cn/post/684490…