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

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事件委托实现原理及优点进行

    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 模块。安装为 ...

    JavaScript事件代理和委托详解

    当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。 这主要得益于浏览器的事件冒泡机制,下面我们具体举个例子来解释如何使用这个特性。 这个例子主要取自...

Global site tag (gtag.js) - Google Analytics