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