我有一些像这样的标记(类只是用于解释):
<ol id="root" class="sortable">
<li>
<header class="show-after-collapse">Top-Line Info</header>
<section class="hide-after-collapse">
<ol class="sortable-connected">
<li>
<header class="show-after-collapse">Top-Line Info</header>
<section class="hide-after-collapse">
<div>Content A</div>
</section>
</li>
</ol>
</section>
</li>
<li>
<header/>
<section class="hide-after-collapse">
<ol class="sortable-connected">
<li>
<header/>
<section class="hide-after-collapse">
<div>Content B</div>
</section>
</li>
</ol>
</section>
</li>
</ol>
即嵌套的可排序列表。然而,可排序的插件就足够了,因为每个li(以下称“item”)都保持其级别,尽管内部列表是连接的。这些项目具有始终可见的标题和处于展开状态时可见的部分,通过单击标题进行切换。用户可以随意添加和删除任何级别的项目;添加顶级项目将在其中包含空巢列表。我的问题是关于新创建的项目的JS初始化:虽然他们将共享一些常见功能,我可以通过
$("#root").on("click", "li > header", function() {
$(this).parent().toggleClass("collapsed");
});
和
li.collapsed section {
display: none;
}
(旁边的问题:这是一个使用详细信息/摘要HTML5标签的合适位置吗?看起来有点不确定那些是否会进入最终规范,我想要一个滑动过渡,所以看起来像无论如何我还需要JS。但是我把问题提交给群众。你好,群众。)
如果根列表是在页面加载时保证存在的唯一(相关)元素,为了使.on()有效工作,我必须将所有事件绑定到该元素并为每个元素拼出精确的选择器,据我所知。因此,例如,要将单独的函数绑定到彼此相邻的两个按钮,我每次都必须完全拼出选择器,àla
$("#root").on("change", "li > section button.b1", function() {
b1Function();
}).on("change", "li > section button.b2", function() {
b2Function();
});
这是准确的吗?在这种情况下,放弃.on()并在将新项目添加到页面时绑定我的事件更有意义吗?如果这会对响应产生影响,那么项目总数最多可能是数十个。
答案 0 :(得分:40)
使用$(<root-element>).on(<event>, <selector>)
绑定事件时,您将创建更少的CPU开销,因为您将绑定到单个“root”元素,而不是可能更多的单个后代元素(每个绑定需要时间......)。 / p>
话虽这么说,当实际事件发生时你会产生更多的CPU开销,因为他们必须将DOM冒泡到“root”元素。
短篇小说:委托在绑定事件处理程序时保存CPU ;当事件触发时(例如,用户点击某些内容),bind会保存CPU。
因此,您需要决定哪一点对性能更重要。添加新元素时是否有可用的CPU?如果是这样,那么直接绑定到新元素对于整体性能来说是最好的,但是如果添加元素是CPU密集型操作,您可能希望委托事件绑定并让事件触发从所有冒泡中创建一些额外的CPU开销。
请注意:
$(<root-element>).on(<event>, <selector>, <event-handler>)
与:
相同$(<root-element>).delegate(<selector>, <event>, <event-handler>)
那:
$(<selector>).on(<event>, <event-handler>)
与:
相同$(<selector>).bind(<event>, <event-handler>)
.on()
是jQuery 1.7中的新功能,如果您使用的是1.7+,那么.delegate(<selector>, <event>, <event-handler>)
只是.on(<event>, <selector>, <event-handler>)
的捷径。
<强>更新强>
这是一个性能测试,显示委托事件绑定比单独绑定到每个元素更快:http://jsperf.com/bind-vs-click/29。可悲的是,此性能测试已被删除。
<强>更新强>
这是一个性能测试,显示直接绑定到元素而不是委托绑定时事件触发更快:http://jsperf.com/jquery-delegate-vs-bind-triggering(请注意,这不是一个完美的性能测试,因为绑定方法包含在测试,但由于delegate
在绑定时运行得更快,这只意味着bind
在谈论触发时相对更快了)
答案 1 :(得分:9)
由于接受的答案有不准确的测试(顺便说一句:测试您的代码,衡量效果,不要盲目遵循一些&#34;规则&#34; - 这不是优化方式完成了!)并且完全错了我发布固定测试: https://jsperf.com/jquery-delegate-vs-bind-triggering/49
证明了这样一个简单的例子,委托或直接绑定之间没有区别
委托总是不好的唯一情况是鼠标移动和滚动等事件 - 每秒触发x次。这是您会注意到性能差异的地方。
如果您在单个事件(即点击次数)上有1分钟的差异(不会发生,但这只是一个例子),您将无法注意到这一点。如果在每秒发生100次的事件上有1ms的差异 - 您将注意到CPU消耗。
只有数千个元素才会对使用委托的性能产生负面影响 - 实际上 - 应该使用这种情况 - 以避免在连接数千个事件处理程序时占用CPU。
因此,如果您确实需要遵循规则(不要这样做) - 除了鼠标移动,滚动和其他可以连续触发的事件外,还可以使用委托。