什么是事件委托?就是把事件的处理委托给别人(别的方式)干。为什么要这样做?因为这样可以某种程度上提高效率,或者能实现原来不能实现的功能。总之有好处我才委托的,不然我自己直接干了。
事件委托实例
我们创建一个列表,当点击具体li的时候,该li改变颜色和字体大小。
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
.active{
color: #9497FF;
font-size: 25px;
}
这里要通过this获取元素,不能通过i获取,因为i在for循环后已经变成最大值。
var liEls = document.querySelectorAll("li");
for (var i = 0; i < liEls.length; i++) {
liEls[i].addEventListener("click",function (event){
this.classList.add("active")
})
}
可以实现类似下面的效果。
上面这段js代码存在的一个问题就是每个li都设置了监听,也就是产生了多个function。如果不是5个li而是更多的内容,性能将不是很高。这时候我们有一个想法,有没有办法把监听事件写到父元素身上,这样只需要监听父元素就可以了。
可以通过下面的代码实现。
这样只使用了一次监听。存在小问题,点击ul的时候,整体都起效果,把ul,li默认样式去除就没事了。或者你判断元素类型是不是li。为了不复杂化代码,突出主题,这里直接把默认样式去掉。
//2.委托给父元素处理
var ulEL = document.querySelector("ul");
ulEL.onclick=function (event){
event.target.classList.add("active")
}
这种方式就是委托,实际上只是一种思想或者处理方式而已。
实例改进
有时候我们想要的不是上面的效果,而是点击后,之前选中的取消选中,然后选中当前选中的,实现单选的效果。
比较推荐的方式是通过定义一个变量记录上次点击的li。或者手动遍历(麻烦,不推荐。),下面的实现方式非常简洁,效率也是非常高的。
//2.委托给父元素处理
var ulEL = document.querySelector("ul");
var lastEl = null;
ulEL.onclick = function (event) {
//和上次点击的是同一个,没必要做任何处理
if (lastEl === event.target) {
return
}
//第一次点击,不需要考虑移除的情况
if (lastEl === null) {
event.target.classList.add("active")
lastEl = event.target
return
}
//需要先移除上次样式的情况
lastEl.classList.remove("active")
event.target.classList.add("active")
lastEl = event.target
}
前面提到过,点击ul会出现集体选中的问题,可以在监听函数开头加上下面这段代码。
//tagName输出结果是大写的
//不处理点击到ul的情况
if (event.target.tagName==="UL"){
console.log("ul")
return
}