jQuery 1.4中的事件委派

时间:2010-06-24 22:08:42

标签: jquery performance hover event-delegation

我有以下代码:

$("ul.relatedAlbums li").hover(function(){
    $(this).css({fontWeight:"bold"});
},
function(){
    $(this).css({fontWeight:"normal"});
});

我听说过关于事件委派和速度性能的好消息。使用jQuery的委托方法,我想它会像:

$("ul.relatedAlbums").delegate("li", "hover", function(){
    $(this).css({fontWeight:"bold"});
},
function(){
    $(this).css({fontWeight:"normal"});
});

但是阅读文档后,它说这种方法就像使用直播活动一样。我一直都明白使用直播活动效率低下。那么,有人可以告诉我最佳做法吗?

3 个答案:

答案 0 :(得分:2)

要指出,.delegate()实际上目前在内部使用.live()并且.deive()将意味着一些框架工作。

除非您动态地向页面添加元素,否则可以将其用作第一个示例。 .live()和.delegate在您有一个交互式页面时会发挥作用,您可以在其中更改其中包含的元素。

编辑:对于downvoters:来自jQuery论坛: http://forum.jquery.com/topic/depreciating-live 引用此代码:

委托:function(selector,types,data,fn){         return this.live(types,data,fn,selector);     },

我的观点是,如果事件合适,特定选择器将限制事件,并且只选择.delegate()并不总是最好的,并且没有全局“总是这样做”。否则,为什么不使用.delegate()来处理那些不是最好的东西。

当WOULD代表合适时?当您的选择器具有共同父级时,例如OP描述的常用li,或者希望通过.delegate()绑定到公共父级。不适用于单数形式的#selector,但值得检验存在倍数或元素动态放置的类或元素选择器。

答案 1 :(得分:1)

授权概念

如果一个父元素中有许多元素,并且你想处理它们的事件 - 不要将处理程序绑定到每个元素。相反,将signle处理程序绑定到它们的父元素,并从event.target获取子元素

然后,什么是JavaScript事件委派?

事件委托是一种简单的技术,您可以通过该技术将单个事件侦听器附加到父元素,该元素将为匹配选择器的所有子项触发,无论这些子项现在是存在还是将来添加。

事件委托使用了两个经常被忽视的JavaScript事件功能:事件冒泡和目标元素

什么是事件冒泡?

在事件冒泡中,事件首先被内部元素捕获并处理,然后传播到外部元素

什么是目标元素?

任何事件的目标元素都是原始元素,并存储在事件对象的属性中。

实施例

<div id="container">
<ul id="list">
    <li><a href="http://domain1.com">Item 1</a></li>
    <li><a href="/local/path/1">Item 2</a></li>
    <li><a href="/local/path/2">Item 2</a></li>
    <li><a href="http://domain4.com">Item3</a></li>
</ul>
</div>

单击#list组中的锚点时,我们希望将其文本记录到控制台。通常我们可以使用.on()方法直接绑定到每个锚点的click事件:

// attach a directly bound event
   $( "#list a" ).on( "click", function( event ) {
    event.preventDefault();
    console.log( $( this ).text() );
    });

虽然这种方法非常好,但也有缺点。考虑在我们已经绑定上述侦听器之后添加新锚点时会发生什么:

// add a new element on to our existing list
 $( "#list" ).append( "<li><a href='#'>Item 5</a></li>" )

如果我们点击新添加的项目,则不会发生任何事情。这是因为我们之前附加的直接绑定事件处理程序。直接事件仅在调用.on()方法时附加到元素。在这种情况下,由于调用.on()时我们的新锚不存在,因此它不会获得事件处理程序。

由于我们知道事件是如何冒泡的,因此我们可以创建一个委托事件:

// attach a delegated event
$( "#list" ).on( "click", "a", function( event ) {
event.preventDefault();
console.log( $( this ).text() );
});

注意我们如何将一个部件从选择器移动到.on()方法的第二个参数位置。第二个选择器参数告诉处理程序监听指定的事件,当它听到它时,检查该事件的触发元素是否与第二个参数匹配。在这种情况下,触发事件是我们的锚标记,它匹配该参数。由于它匹配,我们的匿名函数将执行。我们现在已经附加了一个单击事件监听器,它将监听其子锚点击,而不是仅将未知数量的直接绑定事件附加到现有锚标记。

事件委派的优势是什么?

只将一个事件监听器附加到页面,而不是五百个 动态创建的元素仍将绑定到事件处理程序。

希望这可以帮助您直观地了解事件授权背后的概念,并让您相信代表团的力量! 访问:http://www.scriptcafe.in/2014/03/what-is-event-delegation-in-jquery.html

答案 2 :(得分:0)

事件委托允许您不将事件绑定到单个元素,而是绑定到元素的公共父级。

然而.live()效率很低,因为当事件冒泡时,它会冒泡到文档,这可能距离您可以手动指定的公共父级很远一步。

委托通过允许您指定更近的父级而不是文档来修复此问题。

简而言之,使用.delegate(),它有一些关于.live()的好处,并修复了有问题的方面。

换句话说:.live()默认气泡到文档。您可以指定更接近的上下文,这将消除其低效率。 .delegate()只是帮助你做到这一点的糖方法。