jjzjj

javascript - 绑定(bind)父元素与直接绑定(bind)元素有优缺点吗?

coder 2025-02-18 原文

为了更好地理解 jQuery 性能,我遇到了以下问题。考虑将点击事件绑定(bind)到列表中的项目的两个大致相等的解决方案:

列表项:

<div id="items">
    <div class="item"><a href="#">One</a></div>
    <div class="item"><a href="#">Two</a></div>
    <div class="item"><a href="#">Three</a></div>
</div>

<div id="items2">
    <div class="item"><a href="#">One</a></div>
    <div class="item"><a href="#">Two</a></div>
    <div class="item"><a href="#">Three</a></div>
</div>

注意有两个相同的列表(除了 ID)。现在,考虑使用以下 jQuery 为 item 中的每个 anchor 绑定(bind)客户端事件:

$('#items').on('click', '.item a', function(e) {
   console.log("### Items click"); 
});

$('#items2 .item a').on('click', function(e) {
    console.log("### Items2 click");
});

这实现了相同的结果,因为单击列表中的项目将输出它们各自的消息。

观察被绑定(bind)的事件,在第一种情况下,点击事件被绑定(bind)到 #items 容器,没有事件被绑定(bind)到 child 。但是,在第二种情况下,没有点击事件被绑定(bind)到父元素 #items2,但是每个子元素都有一个点击事件。

现在,我的问题是:明显优于另一个吗?天真,我会假设第一种情况更可取,但缺乏 jQuery 内部知识,它很可能是很可能这两者在底层是等效的。

我准备了一个 fiddle来证明这两种情况。观察 jQuery 为元素构建的事件,是我得出上述假设的地方(您可以在 Web 浏览器的控制台中看到输出)。

最佳答案

除非您要处理大量元素,否则这两种方式都可能无关紧要。问题是什么时候您需要提高效率:绑定(bind)时还是触发时?

免责声明:我并不声称这些测试中的任何一个都是完美的。另外,我只在 Chrome 中测试过。

绑定(bind)时间

我不知道答案,所以我决定尝试并测试所有内容。首先,我假设使用委托(delegate)进行绑定(bind)会快很多(它只需要绑定(bind)一次而不是 X 次)。这似乎是正确的。

http://jsperf.com/on-delegate-vs-not-bind-only

不委托(delegate):慢 100%

触发时间

接下来,我认为不使用委派实际上可能会更快触发事件,因为不需要 DOM 移动来检查事件触发。无论出于何种原因,我都错了:

http://jsperf.com/on-delegate-vs-not-trigger-pls

不委派:慢 60%

(最初的 .trigger 是为了防止 jQuery 缓存委托(delegate)事件,我相信它确实如此。这会影响测试)。

只触发一个项目

然后,我认为不使用委托(delegate)会更快地触发某个特定项目的事件。这也是错误的:

http://jsperf.com/on-delegate-vs-not-trigger-one

不委派:慢 80%

即使它不是最后 sibling ,而是较早的 sibling 之一,也是如此:

http://jsperf.com/on-delegate-vs-not-trigger-one-eq2

深度嵌套

最后,我想委托(delegate)做的很多工作都必须是DOM树解析。这意味着在深度嵌套的 DOM 中使用委托(delegate)并绑定(bind)到一个非常古老的祖先并触发比绑定(bind)到深度嵌套的项目本身并触发需要更长的时间。

最后证明这是正确的:

http://jsperf.com/on-delegate-vs-not-deep-nesting

Delegate: 慢 90%

结论

我不能在这里得出任何重大结论,但如果您要处理大量 DOM,尤其是深度嵌套的 DOM,您可能会考虑使用委托(delegate)进行绑定(bind),而不是直接绑定(bind)。

如果有的话,这些例子教会了我(好吧,无论如何强化)你应该尽量让委派元素尽可能靠近将触发事件的后代。

关于javascript - 绑定(bind)父元素与直接绑定(bind)元素有优缺点吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14618435/

有关javascript - 绑定(bind)父元素与直接绑定(bind)元素有优缺点吗?的更多相关文章

  1. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  2. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  3. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  4. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  5. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  6. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  8. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

  9. ruby - 使用 Nokogiri 和 Ruby 命名元素 "text" - 2

    我在尝试使用Nokogiri构建XML文档时遇到了一个小问题。我想将我的元素之一称为“文本”(请参阅​​下面粘贴代码的最底部)。通常,要创建一个新元素,我会执行类似以下的操作xml.text--但它似乎是.text是Nokogiri已经用来做其他事情的方法。因此,当我写这行时xml.textNokogiri没有创建名为的新元素但只是写了意味着成为元素内容的文本。我怎样才能让Nokogiri实际制作一个名为的元素??builder=Nokogiri::XML::Builder.newdo|xml|xml.TEI("xmlns"=>"http://www.tei-c.org/ns/1.0"

  10. ruby - 在 factory_girl 中有没有办法获取 attributes_for 并为同一个实例元素创建? - 2

    如果我想使用“create”构建策略创建和实例,然后想使用“attributes_for”构建策略进行验证,是否可以这样做?如果我在工厂中使用序列?在Machinistgem中有可能吗? 最佳答案 不太确定我是否完全理解。而且我不是机械师的用户。但听起来您只是想做这样的事情。@attributes=FactoryGirl.attributes_for(:my_object)my_object=MyObject.create(@attributes)my_object.some_property.should==@attributes

随机推荐