关键词:事件委托
原理:利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
例如:如果不加以限制,click事件会一直冒泡到document层次。也就是说,我们可以为整个页面指定一个onclick事件处理程序,而不必给每个可单击的元素分别添加事件处理程序。
下面我们通过一个小例子来了解事件委托
<!-- html代码 -->
<button id="btn">添加标签</button>
<ul id="ul">
<li>1111</li>
<li>2222</li>
<li>3333</li>
</ul>
/*js代码*/
window.onload = function(){
var oUl = document.querySelector("#ul");
var aLi = document.querySelectorAll("li");
var oBtn = document.querySelector("#btn");
var iNow = 3;
oUl.addEventListener('mouseover',function(e){
if(e.target.tagName.toLowerCase() == "li"){
e.target.style.background = "red";
}
});
oUl.addEventListener('mouseout',function(e){
if(e.target.tagName.toLowerCase() == "li"){
e.target.style.background = "";
}
});
oBtn.onclick = function(){
iNow ++;
var oLi = document.createElement("li");
oLi.innerHTML = 1111 *iNow;
oUl.appendChild(oLi);
}
}
我们发现,当我们单击button添加li标签之后,并没有实现鼠标移入背景变色的效果,这是因为我们的循环的只是当前所有标签,当添加新标签之后,新增标签不在循环之内,所以没有效果。
如果加入我们给ul标签添加事件委托,会有什么效果呢?
/*js代码*/
window.onload = function(){
var oUl = document.querySelector("#ul");
var aLi = document.querySelectorAll("li");
var oBtn = document.querySelector("#btn");
var iNow = 3;
oUl.addEventListener('mouseover',function(e){
if(e.target.tagName.toLowerCase() == "li"){
e.target.style.background = "red";
}
});
oUl.addEventListener('mouseout',function(e){
if(e.target.tagName.toLowerCase() == "li"){
e.target.style.background = "";
}
});
oBtn.onclick = function(){
iNow ++;
var oLi = document.createElement("li");
oLi.innerHTML = 1111 *iNow;
oUl.appendChild(oLi);
}
}
我们给ul标签添加了事件委托之后,发现新增的li标签也有利鼠标移入的效果。
这是因为ul标签委托了所有子元素,当鼠标移入移入某个li标签是,就会触发ul 标签委托的监听事件。
事件委托在jQuery中有更简洁的表达:
/*普通方法*/
$('ul li').on('mouseover',function() {}
/*事件委托*/
$('ul').delegate('li','mouseover',function(){}
值得关心的事,由于事件监听抛弃了for循环的方式,代码执行的速度更快,有利于提高性能。
以上代码以演示为主,为了方便,没有考虑浏览器兼容问题