什么是事件委托
事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。
那么为什么需要事件委托呢?
假设我们有一个ul ul里有两个li 我们需要给这两个li添加点击事件 那么我们可能会使用addEventListener 进行监听 添加点击事件 如果li有很多呢 给每一个li添加点击事件 那就会相当的麻烦 当然 你也许很有耐心 但是如果我们想给li动态的添加 那么新添加的li是不会被监听到的。
那我们使用for循环,给每个li添加点击事件呢? 如果li数量很多 这样的话每一次循环都需要创建一个监听器并占用一定的内存,性能会变的很差,所以我们只需要给li的父元素添加一个监听器 就可以达到相同的效果,并且性能会有所提高。
实现
<ul>
<li>一</li>
<li>二</li>
<li>三</li>
<li>四</li>
</ul>
var ul=document.querySelector("ul");
ul.addEventListener('click',function(){
console.log('ok');
})
这样我们点击li时就会执行里面的代码 但是当我们点击ul内部但不是li的区域 还是会触发代码执行 所以我们需要判断点击的标签名是否正确再执行代码
var ul=document.querySelector("ul");
ul.addEventListener('click',function(e){
if(e.target.nodeName==='LI'){
console.log('ok');
}
})
这样上面的问题就解决 但是这样就会引发另一个问题 当li存在子元素并且点击li里面的元素时,是不会执行代码的 所以我们需要再次修改
var ul=document.querySelector("ul");
ul.addEventListener('click',function(e){
var ele=e.target;
while(ele.nodeName!=='LI'){
if(ele===ul){
ele=null;
break;
}
ele=ele.parentNode;
}
if(ele){
console.log('ok');
}else{
console.log('no')
}
})
将当前点击的元素存到ele变量中,判断ele是否是ul如果是则说明并没有点击li或者li内部的元素 所以将ele赋值为空并且退出循环,如果不是ul将ele赋值为ele的父元素再次循环进行判断。
网友评论