在看代码之前,我们先来了解一下什么叫事件委派。
事件委派的定义就是,把原来加给子元素身上的事件绑定在父元素身上,就是把事件委派给父元素。
换句话说,就是把一个本来让下属干的事情交给上司做了。
比如说,鼠标点击事件,本来页面上有很多的鼠标点击事件,需要一个个的去写实现函数,但是如果你把鼠标点击事件交个上司来完成,那么就是你鼠标点击那里的时候,就相当于上司找对应的下属来完成此事件,而不像前面的一个个的去找实现函数。很简单的例子就是给ul中的li加事件:
<ul id="ul1" >
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
如果给每个li添加点击事件,:
var li=document.getElementsByTagName('li');
function A(){
alert(li.innerHTML);
};
li.click=A;
上面的代码alert(li[i].innerHTML)每次运行时都需要 查询li[i].innerHTML的值,且为每一个li都添加了点击事件,这显然会影响代码性能。
这样做有两个很明显的弊端:
1.很耗费资源,因为这种方式是给每个li都加上了事件,li的个数少的话还没事,如果li多的话会很耗费资源。
2.如果后期动态添加li,不会拥有这个弹出事件。
针对以上问题,可以用事件委派来解决。
我们换做事件委托来看看。
var ul=document,getElementById('ul1')
var target = ul.target || ul.srcElement; //兼容处理
alert(target.innerHTML);
这样做的好处就是不在进行查询,减少了DOM操作,极大地改善了代码性能。
如果大家对于事件委派可改善性能这一点不太明白,可以看看下面两个例子:
如果大家不是很好理解,下面给大家提供几个例子:
例子一:
<ul id="ul">
<li>000001</li>
<li>000002</li>
<li>000003</li>
</ul>
<script type="text/javascript">
var ul = document.getElementById('ul');
var li = ul.getElementsByTagName('li');
//用事件委托,通过li的父元素ul,给li添加点击事件
ul.onmouseover = function (event) {
// event对象用于存储事件的数据,例如触发事件的元素、鼠标的位置及状态、按下的键等等;
// event对象只在事件发生的过程中才有效。
// firefox跟IE使用的event的方法不同,IE的event是全局变量,随时可用;firefox需要在事件方法的参数里写event才能用,是运行时的临时变量。
// 在IE/Opera中是window.event,在Firefox中是event;
var event = event || window.event; //event对象
var target = event.target || event.srcElement; //onmouseover事件的调用者
if (target.nodeName.toLowerCase() == 'li') { // onmouseover事件的调用者的DOM元素标签名
target.style.background = 'red';
}
}
ul.onmouseout = function (event) {
var event = event || window.event;
var target = event.target || event.srcElement;
if (target.nodeName.toLowerCase() == 'li') {
target.style.background = '';
}
}
</script>
例子二:
<ul id="resources">
<li><a href="http://opera.com/wsc">Opera Web Standards Curriculum</a></li>
<li><a href="http://sitepoint.com">Sitepoint</a></li>
<li><a href="http://alistapart.com">A List Apart</a></li>
<li><a href="http://yuiblog.com">YUI Blog</a></li>
<li><a href="http://blameitonthevoices.com">Blame it on the voices</a></li>
<li><a href="http://oddlyspecific.com">Oddly specific</a></li>
</ul>
<script>
//事件委派1
(function(){
var resources = document.getElementById('resources');
var links = resources.getElementsByTagName('a');
var all = links.length;
for(var i=0;i<all;i++){
links[i].addEventListener('click',handler,false);
};
function handler(e){
var x = e.target; // Get the link that was clicked
alert(x);
e.preventDefault();
};
})();
//利用事件委派可以写出更加优雅的
(function(){
var resources = document.getElementById('resources');
resources.addEventListener('click',handler,false);
function handler(e){
var x = e.target; // get the link tha
if(x.nodeName.toLowerCase() === 'a'){
alert(x);
e.preventDefault();
}
};
})();
</script>
好了,我们继续讲下面的话题。
上面说到,后期动态增加li不会弹出事件,那么事件委托怎么样?
对于事件委托这位人名币玩家,动态添加的元素,也会被绑定li该有的事件。
<input type="button" id="btn" value="添加li">
<ul id="ul">
<li>111111</li>
<li>22222</li>
<li>33333</li>
</ul>
<script type="text/javascript">
//获取元素
var ul = document.getElementById('ul');
var btn = document.getElementById('btn');
//鼠标覆盖
ul.onmouseover = function (event) {
var event = event || window.event;
var target = event.target || event.srcElement;
if (target.nodeName.toLowerCase() == 'li') {
target.style.background = 'red';
}
}
//鼠标离开
ul.onmouseout = function (event) {
var event = event || window.event;
var target = event.target || event.srcElement;
if (target.nodeName.toLowerCase() == 'li') {
target.style.background = '';
}
}
//点击添加li按钮
btn.onclick = function () {
var lisLength = ul.getElementsByTagName('li').length;
var newLi = document.createElement('li');
newLi.innerHTML = 11111*(lisLength+1);
ul.appendChild(newLi);
}
</script>
很显然,使后期添加的li也具有同样的功能,这是普通事件做不到的。我们可以用事件委派来为动态添加的元素添加事件。
所以说,在对元素进行事件绑定的时候,推荐使用事件委派,它既可以为动态添加的元素附上效果,也可以改善代码性能,何乐而不为呢~
事件委派乍一看好像很难,但是多试几个例子,就能够理解啦。
大家还在等什么?快去试试吧~
Biu~~~~我先去也~~