事件委托

定义

何为事件委托,事件委托就是我们可以把本身应该在自己身上的事件触发,委托给别的元素上,让它来代替事件触发。

原理

主要是通过事件冒泡的特性,触发点击事件之后,PC 端的点击事件是由 300 毫秒的延迟的,当前元素触发之后,会一直向上冒泡,直到 document 才会停止冒泡。注意:任意一层阻止冒泡将会停止。

好处

  1. 当我们有大量的子元素,我们为了点击它,需要在它的身上都加上一个点击事件,知道个数还好,假如我们不知道个数,想绑定事件都没法绑定。所以我们需要借助它的父亲来实现点击事件。只需要指定一个事件就可以管理一类型事件。

  2. 添加到页面上的事件处理程序的数量直接关系到页面的整体性能,访问 dom 次数越多,就会引起越多的浏览器的重排与重绘。延迟整个页面的交互事件。性能优化中很重要的一点就是减少与dom元素的操作。如果我们利用事件委托,与dom操作只需要交互一次,提高性能。

  3. 创建函数是需要开辟内存的,我们 for 循环出来不知道多少个函数,会占用多少的内存空间,内存不足。

实现

给 li 添加点击事件
<ul id="ul1">
   <li></li>
   <li></li>
   <li></li>
</ul>

<script>
    var ul = document.getElementById('ul1');
    var li = ul.getElementsByTagName('li');
    for (var i = 0; i < li.length; i++) {
        li[i].onclick = function () {
            console.log(i);
        }
    }
</script>
给 ul 添加点击事件
ev 在 IE 下有兼容性的 使用 event
target 在 IE 使用的是 srcElement
<ul id="ul1">
   <li></li>
   <li></li>
   <li></li>
</ul>

<script>
    var ul = document.getElementById('ul1');
    ul.onclick = function (ev) {
        var ev = ev || event;
        var target = ev.target || ev.srcElement;
        if (target.nodeName.toLowerCase() === 'li') {
            console.log(target.innerHTML);
        }
    }
</script>

for 动态添加 li

利用 for 来遍历过的 li,绑定的事件只会应用到目前存在于 dom 元素中的,但是动态添加的是没有绑定事件的。

为了将新增加的 li 也给绑定上 li, 需要添加 li 到dom元素中之后再一次的调用 for 重新遍历一次,重新绑定事件。

事件委托添加新的 li

这个就不一样,因为 li 是存在与 ul 的内部的,我们利用委托的方式,不管是原有的 li ,还是新增加的 li ,都是会绑定事件的。这样子。就能够对性能有很大的提升。


<script>
    var ul = document.getElementById('ul1');
    var btn = document.getElementById("btn");
    ul.onclick = function (ev) {
        var ev = ev || event;
        var target = ev.target || ev.srcElement;
        if (target.nodeName.toLowerCase() === 'li') {
            console.log(target.innerHTML);
        }
    }

    btn.onclick = function(){
        num++;
        var li = document.createElement('li');
        li.innerHTML = num;
        ul.appendChild(li);
    };
</script>