我有一些这样的标记(类只是为了说明):
<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; }
(旁听的问题:这是使用details / summary HTML5标签的合适位置吗?对于这些标签是否甚至可以将其纳入最终规范似乎有些疑惑,我想进行一次滑动过渡,所以似乎我想无论如何都需要JS。但是我把这个问题扔给了大众。你好,大众。)
如果根列表是页面加载时保证存在的唯一(相关)元素,则.on()才能有效工作,我必须将所有事件绑定到该元素,并为每个事件拼出精确的选择器,因为明白它。因此,例如,要将单独的功能绑定到彼此相邻的两个按钮上,我每次必须完整拼出选择器,
$("#root").on("change", "li > section button.b1", function() { b1Function(); }).on("change", "li > section button.b2", function() { b2Function(); });
准确吗?既然如此,在将新项添加到页面时放弃.on()并绑定我的事件是否更有意义?如果响应有所不同,则项目总数最多可能会打几十个。
使用绑定事件时,将创建较少的CPU开销,$(<root-element>).on(<event>, <selector>)因为将绑定到单个“根”元素,而不是绑定到更多的单个后代元素(每个绑定都需要时间…)。
$(<root-element>).on(<event>, <selector>)
话虽如此,当实际事件发生时,您将招致更多的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>)。
.on()
.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在谈论触发时相对而言甚至更快)
delegate
bind