之前我们说过用 for 循环绑定事件 没看过的点这里 今天我们介绍一种更加方便的方法,就是事件委托,也叫事件代理;
件事委托是什么
事件委托:简单说就是把一个事件交给别人来完成,就是利用冒泡原理,将事件绑定到节点的父级节点上,触发执行效果。
件事委托的好处
- 提高Javascript性能。假如现在有个 ul,里面有10个 li,每个 li 都需要触发事件,之前我们说过可以用 for 循环,遍历所有的 li,然后添加事件,这样会影响Javascript性能。
- 动态绑定事件,可以给暂未存在的元素绑定事件
举个栗子
这里要用到event对象,event对象有个 target 属性,可以返回触发此事件的元素。然后通过nodeName获取节点名称,再用toLowerCase()转换成小写(可以省略)
<body>
<ul id="ul">
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
<li>5555</li>
</ul>
<script type="text/javascript">
var oUl = document.getElementById("ul");
oUl.onclick = function(ev){
// 获取事件对象,兼容IE
var ev = ev || window.event;
// 获取事件源(就是当前操作的元素) 标准浏览器用ev.target;IE浏览器用event.srcElement
var target = ev.target || ev.srcElement;
// toLowerCase()把nodeName返回的值转换成小写,如果不写则需要 == "LI"
if(target.nodeName.toLowerCase() == 'li'){
alert("abc");
}
};
</script>
</body>
这样一来,相对 for 循环,如果 li 数量很多的话,大大提高了Javascript性能,因为每次只执行一次dom操作,不需要再去遍历 li 元素。
除了提高Javascript性能之外,还可以动态的绑定事件,给后来添加的元素也能享受此权利,举个栗子:
<body>
<ul id="ul">
<input type="button" name="" id="btn" value="添加li" />
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
<li>5555</li>
</ul>
<script type="text/javascript">
var oUl = document.getElementById("ul");
var oBtn = document.getElementById("btn");
// 添加鼠标移入效果
oUl.onmouseover = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.style.background = "#f00";
}
};
// 添加鼠标移出效果
oUl.onmouseout = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.style.background = "#fff";
}
};
// 添加新的li
oBtn.onclick = function(){var oLi = document.createElement('li');
oLi.innerHTML = 6666;
oUl.appendChild(oLi);
};
</script>
</body>
无论添加多少个 li,都会自动绑定鼠标移入移出事件,不要再去遍历 li 了,这就是事件委托的好处
《JS高设 3rd》中列出了几种最适合采用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress