【问题标题】:Is binding events in jQuery very expensive, or very inexpensive?jQuery 中的绑定事件是非常昂贵还是非常便宜?
【发布时间】:2010-10-28 16:46:51
【问题描述】:

我刚刚编写了一个 $().bind('event') 函数,然后担心如果 jQuery 必须遍历 DOM 中的每个元素来绑定这个事件,这种调用可能会非常昂贵。

或者,它可能与活动一样高效。我读过的 jQuery 文档并没有说明这一点。有意见吗?

【问题讨论】:

    标签: javascript jquery performance events


    【解决方案1】:

    有两件事可以使您的事件绑定代码变慢:选择器和绑定数。两者中最关键的是绑定数,但选择器可能会影响您的初始性能。

    就选择器而言,只要确保您不使用像 .myclass 这样的纯类名选择器。如果您知道myclass 的类将始终位于<div> 元素中,请将您的选择器设置为div.myclass,因为它将帮助jQuery 更快地找到匹配的元素。另外,不要利用 jQuery 让你给它巨大的选择器字符串。它可以用字符串选择器做的所有事情,它也可以通过函数做,这是故意的,因为它(勉强承认)这样做更快,因为 jQuery 不必坐下来解析你的字符串来弄清楚什么你要。所以你可以不做$('#myform input:eq(2)');,而是做$('input','#myform').eq(2);。通过指定一个上下文,我们也不会让 jQuery 在它不需要的任何地方看起来,这要快得多。 More on this here.

    至于绑定的数量:如果你有一个相对中等数量的元素,那么你应该没问题 - 任何多达 200、300 个潜在元素匹配在现代浏览器中都可以正常运行。如果你有更多,你可能想转而研究事件委托。

    什么是事件委托?本质上,当你运行这样的代码时:

    $('div.test').click(function() {
        doSomething($(this));
    });
    

    jQuery 在幕后做了这样的事情(为每个匹配的元素绑定一个事件):

    $('div.test').each(function() {
        this.addEventListener('click', function() {
            doSomething(this);
        }, false);
    });
    

    如果您有大量元素,这可能会变得低效。通过事件委托,您可以将完成的绑定数量减少到一个。但是怎么做?事件对象有一个target 属性,可以让您知道事件作用于哪个元素。所以你可以这样做:

    $(document).click(function(e) {
        var $target = $(e.target);
        if($target.is('div.test')) { // the element clicked on is a DIV
                                     // with a class of test
           doSomething($target);
        }
    });
    

    谢天谢地,您实际上不必使用 jQuery 编写上述代码。 live 函数被宣传为一种将事件绑定到尚不存在的元素的简单方法,它实际上能够通过使用事件委托并在操作发生时检查目标是否与您指定的选择器匹配来做到这一点给它。当然,这有一个副作用,即在速度很重要时非常方便。

    故事的寓意?如果您担心绑定的数量,您的脚本只需将 .bind 替换为 .live 并确保您有智能选择器。

    但请注意,.live 并不支持所有事件。如果你需要它不支持的东西,你可以查看livequery 插件,它是在类固醇上运行的。

    【讨论】:

    • 需要注意的是,由于添加了delegate,您的脚本可能会比使用live 时更快。
    • 我发现 .myClass 比 div.myClass 快:jsperf.com/div-test-vs-test
    • @CharlieS:对于现代浏览器来说,这一直是正确的,早在 2009 年,当担心 IE 7,8 更为普遍时,div.test 是一个更好的整体选择。
    • 提醒 .live() 方法自 1.7 版以来已被弃用并从 1.9 版中删除
    【解决方案2】:

    基本上,你不会做得更好。 它所做的只是在您选择的每个元素上调用 attachEventListener()。

    仅在解析时,此方法可能比在每个元素上设置内联事件处理程序更快。

    一般来说,我认为这是一项非常便宜的手术。

    【讨论】:

      猜你喜欢
      • 2022-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 2011-04-17
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多