js事件冒泡的高级应用
事件冒泡
前面这篇 文章介绍了js的事件冒泡过程.
利用事件的冒泡阶段, 我们可以轻松的实现事件代理.
过程如下:
<!--给这个结构的a绑定点击事件-->
<div id="box">
<ul>
<li>
<a></a>
</li>
<li>
<a></a>
</li>
<li>
<a></a>
</li>
<li>
<a></a>
</li>
<li>
<a></a>
</li>
</ul>
</div>
// 传统的我们这么做
var box = document.getElementById('box'),
oA = box.getElementsByTagName('a'),
len = oA.length, i = 0;
for ( ; i < len; i++ ) {
oA[i].onclick = function() {
// doSomething
}
} <!--more-->
当然,从功能的角度来说. 上面的做法没有任何问题, 但是假如盒子里面的内容是动态的, 实时改变的. 我们需要怎么做? 每次都遍历绑定? 再说, 这样一个一个的去绑定确实太费事 . 遇到绑定事件中需要用到变量i的情况还要去使用闭包…
oA[i].onclick = (function(i) {
// doSomething
})(i);
事件代理
既然事件的传播过程是向上冒泡的, 为啥不设置一个监听器, 让所有在它之下的元素的事件 响应都让这个监听器来做呢? 我们要做的只是在响应过程中判断一下事件源不就OK了!
// 对上面的代码进行优化, 把事件都绑定到box盒子上
var box = document.getElementById('box');
box.onclick = function() {
var target = e.srcElement ? e.srcElement : e.target; // 前者是ie, 后者标准DOM
// 这样就获取了真正请求点击事件的源dom元素.
}
还有一个问题就是, 在box下面的元素有很多, 怎么才能确定是从a发出的呢? 这就涉及到事 件源的过滤.
box.onclick = function() {
var target = e.srcElement ? e.srcElement : e.target, // 前者是ie, 后者标准DOM
tNodeName = target.nodeName.toLowerCase();
switch(tNodeName) {
case a:
// doSomething
break;
case ...:
break;
default:
break;
}
}
这样的好处是在这个监听器下的所有点击事件都能通过box进行代理. 而我们不必去为每个 元素都绑定一下点击事件.