4

通过性能将事件处理程序附加到 jQuery 中的元素的最佳方法是什么?

我想将事件处理程序附加到它们的所有元素都是静态的,我们没有任何生成和动态创建的元素:

<div class="foo"></div>
<div class="bar"></div>
<div class="qux"></div>

我想将click事件处理程序分别附加到所有它们,我有三个选项。


一、直接附加事件处理程序

在这个经典方法中,我将事件处理程序直接附加到元素:

$('.foo').on('click', f);
$('.bar').on('click', g);
$('.qux').on('click', h);

二、多次将事件处理程序附加到父级

在此方法中,我将多次为每个元素将事件处理程序附加到父处理程序,而不是以前的方法:

$('body').on('click', '.foo', f);
$('body').on('click', '.bar', g);
$('body').on('click', '.qux', h);

三、一次将事件处理程序附加到父级

此方法与之前的方法相同,只是有一个不同。我将只附加一次事件处理程序,我将在处理程序本身中检查所需的选择器:

$('body').on('click', function (e) {
    var $elem = $(e.target);

         if ($elem.is('.foo')) { f(); }
    else if ($elem.is('.bar')) { g(); }
    else if ($elem.is('.qux')) { h(); }
});

我想知道哪个性能最好?

4

3 回答 3

2

决定将其从评论移至答案。
IMO,事件绑定的操作对性能影响不大。应该考虑的是在处理程序中执行的操作。这就是为什么第三种选择可能是最糟糕的。

第二个选项,AFAIK,通常用作事件委托。大多数情况下,如果您想将事件绑定到元素,则将在将来创建,即通过 AJAX:

$(document).on('click', '.futureElement', alert);
$.post("someurl", {data: someData}, function () {
   //create element with class .futureElement
});

一种是用jQuery绑定事件的常用方式,因此是目前最快的一种。

于 2013-06-03T12:37:26.230 回答
0

您的第三个解决方案绝对是最糟糕的一个,因为它会在触发 click 事件时检查元素的类。

这里的瓶颈是 jQuery 选择器解析,所以第一个解决方案是最有效和可读的。

于 2013-06-03T12:18:51.300 回答
0

让我不同意其他答案。

甚至这里的测试http://jsperf.com/test-so-1说最后一个选项是最快的。但我可以尝试解释原因。

在这种情况下:

$('body').on('click', '.foo', f);

我们使用标准的 jquery 方式来绑定委托事件。我们将一个事件绑定到body并要求 jQuery 对照.foo选择器检查它。每个事件都有一个属性e.target,它实际上启动了事件。但是事件会在 DOM 中冒泡,因此我们的.foo选择器可以匹配e.target. 所以 jQuery 必须做额外的遍历,例如找到所有的父级e.target并对照选择器检查它.foo

它是我们仅直接检查的 3d 选项e.target

如果.foo选择器接近,body则性能没有太大差异。但是如果.foo选择器在 DOM 树的深处,jQuery 必须遍历很多e.target.

证明它的测试:

http://jsfiddle.net/xDyuJ/1/

http://jsfiddle.net/xDyuJ/2/

您可以看到它仅测量事件执行。3d 案例快两倍多。间隙将相对于 DOM 树中元素的位置发生变化。

于 2013-06-03T12:57:57.190 回答