`
yeah1900
  • 浏览: 1998 次
  • 来自: ...
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Javascript的事件委托

阅读更多

原文: http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/#

 

传统的事件处理

所谓事件委托即使用单个Event Handler来管理页面上特定的一类事件。这并不是什么新的idea,但对于Web应用的性能而言,是很重要的。比如,有时候,你可能会写如下的代码:

document.getElementById("help-btn").onclick = function(event){
    openHelp();
};

document.getElementById("save-btn").onclick = function(event){
    saveDocument();
};

document.getElementById("undo-btn").onclick = function(event){
    undoChanges();
}; 

它为页面上每一个可交互的元素提供了一个Event Handler。在一个小型的Web应用中,这可能问题不明显。但如果这是一个大型的网站,存在大量的交互,这么多的handler可能就会出现性能问题了。可以想象,为了处理数以百计的交互,我们需要将大量的DOM元素和时间处理代码绑定起来。这会占用大量的内存,进而导致整个应用运行变慢。而事件委托就可以用来解决这个问题。

事件冒泡和捕获(Event Bubbling / Capturing)

在早期Web开发的年代,浏览器厂商需要考虑一个问题:当用户在Web页面上点击一个区域,如何判断他实际正在进行互交互的元素。与之相关的是我们如何定义交互。在一个元素内点击的操作是有二义性的。如下图所示,如果用户点击了一个button元素,这个交互发生在button内部,同时我们也可以说它发生在body元素的内部,同时还在html元素的内部。

      在这个问题被提出来的时候,当时的两个主要浏览器(Netscape Navigator 和 Internet Explorer)采取了不同方式来解决这个问题。Netscape使用了一种叫做事件捕捉的机制,事件首先发生在DOM树上最高层的元素上,然后逐层往下传递到最深的被影响的元素上。所以,在上述例子中,点击事件首先由document元素来处理,然后是html元素,接下来是body,最后才是button元素。

      Internet Explorer正好使用了完全相反的方式。他们称之为事件冒泡:最底层的元素应该首先接受到这个时间,然后才是它的父节点,祖父节点……一直到最高层的document元素。值得注意的是,虽然document和<html>元素对应的是页面上同一个可视元素,但它们在DOM树上却是父子关系。Event Bubbling的终点是document元素。

在定义DOM的时候,W3C显然注意到了两种不同方式各自的好处,因此我们现在使用的DOM Level 2事件机制中同时包含了这两种方式。一开始document元素接收到这个事件,进入捕获阶段,将其传递到最底层的元素。在这个元素的处理逻辑完成以后,进入冒泡阶段,将其传递回到document。在DOM Level2事件API中,addEventListener方法接受三个参数:要处理的事件名,事件处理函数,一个bool值(true表示在捕获阶段处理事件,而false表示在冒泡阶段处理事件)。多数Web开发人员经常会被告知使用false作为参数值,以保持和IE中的attachEvent方法相同的行为。比如:

//bubbling phase handler
document.addEventListener("click", handleClick, false);

//capturing phase handler
document.addEventListener("click", handleClick, true);

使用形如 element.onclick = function(){} 的方式来绑定事件的方式,即DOM Level 1的事件机制,是在冒泡阶段处理事件的(向前兼容性)。大多数浏览器(除了IE)都支持DOM Level 2事件机制,也就是说同时支持事件捕获和冒泡。IE仍然使用的是其专有的,仅支持冒泡方式的事件处理机制。

 

事件委托的关键就是使用事件冒泡的特性在DOM最高层的元素来处理它们(通常是document)。当然,不是所有的事件都支持冒泡(如onsubmit,onfocus,onblur这一类不和输入设备直接相关的时间等),但是鼠标和键盘事件都可以(包括onclick)。而且,很幸运的是,这些通常是你会感兴趣的。重新考虑之前的例子,你可以在document的事件处理函数中,检查事件的目标元素,并完成相应的逻辑。

document.onclick = function(event){
    //IE doesn't pass in the event object
    event = event || window.event;
    
    //IE uses srcElement as the target
    var target = event.target || event.srcElement;    

    switch(target.id){
        case "help-btn":
            openHelp();
            break;
        case "save-btn":
            saveDocument();
            break;
        case "undo-btn":
            undoChanges();
            break;
        //others?
    }
};

事件委托可以让同一事件的处理入口都汇集到一个函数中。所有的click事件现在都会先被单个函数所处理,并根据时间的对象元素委托给合适的函数。同样的,我们把它应用于mousedown , mouseup , mousemove , mouseover , mouseout , dblclick , keyup , keydown , 和keypress 事件. 这里要注意的一点就是,由于mouseover 和mouseout事件的特性(仅当鼠标移出容器时才会触发 mouseout),事件代理对它们来说并不是很实用。

当然,你也可以通过事件捕获来完成Event delegation,但这仅在支持事件捕获的浏览器中有效,也就是说IE不支持该方式。

好处

对于一个web应用来说,事件代理具有以下几点好处:

  1. 较少的事件处理函数.
  2. 占用更少的内存.
  3. 减少了Javascript和DOM之间的耦合.
  4. 在改变元素的innerHTML时,不用去移除绑定事件处理函数 .

相比于传统的事件处理方式,事件委托提高了大型web应用的总体性能。它对于Javascript库至关重要,如YUIjQuery 已经使用了这种机制。实现事件委托并不难,但是在用户界面的性能上的提高确实非常显著的。这在你将大量的事件处理函数合并为一个的时候,尤其明显。试试事件委托机制吧!

 

分享到:
评论

相关推荐

    JavaScript事件委托的技术原理 – WEB骇客1

    JavaScript事件委托是一种优化网页性能和管理动态元素的事件处理策略。在传统的事件处理方式中,我们通常会在每个需要响应事件的元素上单独设置事件监听器。然而,这种方法在元素数量较多或者元素动态增删时,可能...

    javascript事件委托的用法及其好处简析.doc

    javascript事件委托的用法及其好处简析.doc

    JavaScript事件委托实现原理及优点进行

    JavaScript事件委托是一种高效处理大量动态DOM元素事件的技术,它基于事件冒泡机制,将事件监听器添加到父元素而非所有子元素上。这种技术的主要优点在于性能优化和动态添加DOM元素的适应性。 1. **什么是事件委托...

    JavaScript事件委托原理与用法实例分析

    JavaScript事件委托是一种优化事件处理的策略,它基于事件流(冒泡和捕获)的机制,使得可以在一个共同的祖先元素上处理多个子元素的事件,而不是为每个子元素单独绑定事件处理器。这种方式有助于减少内存消耗,提高...

    javascript事件委托的方式绑定详解

    也许偶尔就会遇到“事件委托”,但是,大多数时说的是“事件绑定”,对于“事件委托”,或是不提,或是浅尝辄止。对于我这个比较好奇的人来说,实在很蛋疼。尤其是想更多的了解“事件委托”的时候。

    JavaScript事件委托实例分析

    JavaScript事件委托是一种优化网页性能的事件处理技术,它利用了事件冒泡的原理,将事件处理器绑定到一个共同的父元素上,而不是每个子元素都单独绑定。这种方法减少了内存消耗和DOM操作,尤其是在动态添加或删除...

    javascript事件委托的用法及其好处简析

    在Web前端开发中,JavaScript事件委托是一种高效处理DOM元素事件的技术。事件委托的核心思想是利用了事件冒泡机制,即子元素上触发的事件会向上冒泡到父级元素。通过在父级元素上设置事件监听器,可以捕捉到子元素的...

    JavaScript事件委托技术实例分析

    JavaScript事件委托技术是一种有效的事件处理机制,它主要用于提高程序性能,尤其是在处理大量具有相似事件响应的DOM元素时。这种技术基于事件冒泡原理,即在一个DOM元素上触发的事件会向上冒泡到更上层的DOM元素。...

    JavaScript事件委托用法分析

    JavaScript事件委托是一种利用事件冒泡原理来管理事件的技术,它允许开发者将事件监听器添加到一个父元素上,而不是给每一个子元素单独添加事件监听器。这种方式在处理大量子元素或动态生成的元素时非常有效,可以...

    【JavaScript源代码】JavaScript给事件委托批量添加事件监听详细流程.docx

    ### JavaScript事件委托详解 #### 一、事件委托概念 **事件委托**是一种常见的JavaScript编程技巧,主要用于优化事件处理。它的核心思想是利用事件冒泡机制,将原本应该绑定在子元素上的事件处理器绑定在其父元素...

    JavaScript事件委托的技术原理探讨示例

    JavaScript事件委托是一种优化网页性能和简化事件处理的策略。它基于事件冒泡的特性,即事件从最深的节点开始,然后逐级向上层元素传播。通过在父元素上设置事件监听器,而不是在每个子元素上分别设置,可以极大地...

    Evt:Javascript 事件委托

    Javascript 事件委托。 应该比,因为它有命名空间 :smiling_face_with_sunglasses: . 缩小时约 2.3kb,gzip 时约 930 字节。 应用程序接口 // create a new instance var evt = new Evt ( '#mydiv' ) ; // Works ...

    JavaScript之事件委托.pdf

    JavaScript中的事件委托是一种高效处理大量动态元素事件的技术,它的核心思想是将事件监听器绑定到父级元素上,而不是直接绑定到每一个子元素。这种方法基于事件冒泡的机制,能够减少对DOM的操作,提高页面性能。 ...

    Dega:纯 JavaScript 事件委托库

    纯 JavaScript 上的事件委托库。 简单,小,只有 1.2kb 压缩和大约 620 字节的 gzip。 在最新的 Chrome、Firefox、Safari、Opera、IE9+ 上测试。安装您可以使用 Dega 作为全局对象、AMD 或 CommonJS 模块。安装为 ...

Global site tag (gtag.js) - Google Analytics