事件委派
Web应用都是由事件驱动运转的。我喜欢事件处理,尤其喜欢自己定义事件。它能使你的产品可扩展,而不用改动核心代码。有一个很大的问题(也可以说是功能强大的表现),是关于页面上事件的移除问题。你可以对某个元素安装一个事件监听器,事件监听器就开始运转工作。
但页面上没有任何指示说明这有个监听器。因为这种不可表现的问题 (这尤其让一些新手头疼) ,以及像IE6这样的”浏览器“在太多的使用事件监听时会出现各种的内存问题,你不得不承认尽量少使用事件编程是个明智的做法,于是事件委托就出现了。
当页面上某个元素上的事件触发时,而在 DOM 继承关系上,这个元素的所有子元素也能接收到这个事件,这时你可以使用一个在父元素上的事件处理器来处理,而不是使用一堆的各个子元素上的事件监听器来处理。究竟是什么意思?这样说吧,页面上有很多超链接,你不想直接使用这些链接,想通过一个函数来调用这个链接,HTML代码是这样的:
广州网站建设,网站建设,广州网页设计,广州网站设计
- <h2>Great Web resources</h2>
- <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>
常见的做法是通过循环这些链接,将每个链接上附加一个事件处理器:
- // 典型的事件处理例子
- (function(){
- var resources
- = document.getElementById('resources');
- var links =
- resources.getElementsByTagName('a');
- var all =
- links.length;
- for(var i=0;i<all;i++){
- // Attach a listener to each link
- 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('Event
- delegation:' + x);
- e.preventDefault();
- }
- };
- })();
因为点击事件就发生在这些页面元素里,你要做的就是比较它们的 nodeName,找出应该回应这个事件的那个元素。免责声明:上面说的这两个关于事件的例子,在所有浏览器里都能运行,除了IE6,在IE6上你需要使用一个事件模型,而不是简单的W3C的标准实现。这也就是我们推荐使用一些工具包的原因。
广州网站建设,网站建设,广州网页设计,广州网站设计
这种方法的好处并不是仅限于把多个事件处理器缩减为一个。你想想,举个例子,你需要动态的往这个链接表里追加更多的链接。使用事件委托后,你就不需要做其它修改了;否则的话,你需要重新循环这个链接表,重新给每个链接安装事件处理器。