将复杂元素添加到页面时,事件委派与直接绑定 [英] event delegation vs direct binding when adding complex elements to a page

查看:128
本文介绍了将复杂元素添加到页面时,事件委派与直接绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些这样的标记(类仅用于解释):

I have some markup like this (classes are just for explication):

<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初始化:虽然他们将共享一些常见的功能,我可以通过

That is, nested sortable lists. The sortable plugin suffices, however, since each li (hereafter "item") maintains its level, though the inner lists are connected. The items have an always-visible header and a section visible when in expanded state, toggled by clicking the header. The user can add and remove items from either level at will; adding a top-level item will include an empty nest list inside it. My question is with respect to JS initialization of the newly created item: While they will share some common functionality, which I can cover via

$("#root").on("click", "li > header", function() {
  $(this).parent().toggleClass("collapsed");
});

li.collapsed section {
  display: none;
}

(附带问题:这是否适合使用详情/摘要HTML5标签?看起来有点不确定它们是否会进入最终规范,我想要一个滑动过渡,所以看起来我还需要JS。但是我把这个问题提交给大众。你好,群众。)

(Side question: would this be an appropriate place to use the details/summary HTML5 tags? It seems sort of iffy about whether those will even make it into the final spec, and I want a sliding transition, so it seems like I'd need JS for that anyway. But I throw the question to the masses. Hello, masses.)

如果根列表是保证在页面加载时存在的唯一(相关)元素,为.on()有效地工作,我有根据我的理解,将所有事件绑定到该元素并拼出每个事件的精确选择器。因此,举例来说,为了将单独的函数绑定到彼此相邻的两个按钮,我必须每次都完全拼出选择器,然后进行拼写; la

If the root list is the only (relevant) element guaranteed to be in existence at page load, for .on() to work effectively, I have to bind all the events to that element and spell out the precise selector for each, as I understand it. So, for example, to tie separate functions to two buttons right next to each other, I'd have to spell out the selector in full each time, à la

$("#root").on("change", "li > section button.b1", function() {
  b1Function();
}).on("change", "li > section button.b2", function() {
  b2Function();
});

这是准确的吗?在这种情况下,放弃.on()并在将新项目添加到页面时绑定我的事件更有意义吗?如果这会对响应产生影响,那么项目总数最多可能是数十个。

Is that accurate? That being the case, does it make more sense to forgo .on() and bind my events at the time the new item is added to the page? The total number of items will probably number in the dozens at most, if that makes a difference in the response.

推荐答案

你将会使用 $(< root-element>)。on(< event>,< selector>)绑定事件时创建的CPU开销更少,因为您将绑定到一个root元素,而不是可能更多的单个后代元素(每个绑定需要时间......)。

You will create less CPU overhead in binding the events using $(<root-element>).on(<event>, <selector>) since you will be binding to a single "root" element instead of potentially many more single descendant elements (each bind takes time...).

话虽如此,当你说,你将产生更多的CPU开销实际事件发生时,他们必须将DOM冒泡到根元素。

That being said, you will incur more CPU overhead when the actual events occur as they have to bubble up the DOM to the "root" element.

短篇小说:委托在绑定时保存CPU 事件处理程序;绑定在事件触发时保存CPU(例如,用户点击某些内容)。

Short-story: delegate saves CPU when binding event handlers; bind saves CPU when events trigger (e.g. a user clicks something).

因此,您可以决定哪个点对性能更重要。添加新元素时是否有可用的CPU?如果是这样,那么直接绑定到新元素对于整体性能来说是最好的,但是如果添加元素是CPU密集型操作,您可能希望委托事件绑定并让事件触发从所有冒泡中创建一些额外的CPU开销。

So it's up to you to decide what point is more important for performance. Do you have available CPU when you add the new elements? If so then binding directly to the new elements would be the best for overall performance however if adding the elements is a CPU intensive operation you will probably want to delegate the event binding and let the event triggering create some extra CPU overhead from all the bubbling.

请注意:

$(<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-)的捷径处理程序>)

.on() is new in jQuery 1.7 and if you are using 1.7+ then .delegate(<selector>, <event>, <event-handler>) is just a short-cut for .on(<event>, <selector>, <event-handler>).

更新

< s>这是一个性能测试,表明委托事件绑定比单独绑定到每个元素更快: http://jsperf.com/bind-vs-click/29 。可悲的是,此次性能测试已被删除。

Here is a performance test showing that it is faster to delegate event binding than to bind to each element individually: http://jsperf.com/bind-vs-click/29. Sadly this performance test has been removed.

UPDATE

这是一个性能测试,显示直接绑定到元素而不是委托绑定时事件触发更快: http://jsperf.com/jquery-delegate-vs-bind-triggering (请注意,这不是'一个完美的性能测试,因为绑定方法包含在测试中,但由于 delegate 在绑定时运行得更快,这只意味着 bi在讨论触发时,nd 相对更快。

Here is a performance test showing that event triggering is faster when you bind directly to elements rather than delegate the binding: http://jsperf.com/jquery-delegate-vs-bind-triggering (Note that this isn't a perfect performance test since the binding methods are included in the test, but since delegate runs faster on binding it just means that bind is even faster relatively when talking about triggering)

这篇关于将复杂元素添加到页面时,事件委派与直接绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆