为什么在这种DOM操作的情况下事件委托更好 - jQuery

时间:2013-09-07 17:16:39

标签: jquery javascript-events

<div id="tours">
  <h1>Guided Tours</h1>
  <ul>
    <li class="usa tour" data-discount="299">
      <h2>New York, New York</h2>
      <span class="details">$1,899 for 7 nights</span>
      <button class="book">Book Now</button>
    </li>
    <li class="europe tour" data-discount="176">
      <h2>Paris, France</h2>
      <span class="details">$2,299 for 7 nights</span>
      <button class="book">Book Now</button>
    </li>
    <li class="asia tour" data-discount="349">
      <h2>Tokyo, Japan</h2>
      <span class="details">$3,799 for 7 nights</span>
      <button class="book">Book Now</button>
    </li>
  </ul>
</div>

以上是HTML代码,下面是DOM操作部分。

$(document).ready(function(){
  $("li.tour button.book").on("click", function(){
    var tour = $(this).closest(".tour");
    var discount = tour.data("discount");
    var message = $("<span>Call 1-555-jquery-air for a $" + discount + "</span>");
    tour.append(message);
    $(this).remove();
  });
});

上面的代码工作正常。但似乎采用这种方法的正确方法如下,他们称之为事件委托

$(document).ready(function(){
  $("li.tour").on("click", "button", function(){
    var tour = $(this).closest(".tour");
    var discount = tour.data("discount");
    var message = $("<span>Call 1-555-jquery-air for a $" + discount + "</span>");
    tour.append(message);
    $(this).remove();
  });
});

2 个答案:

答案 0 :(得分:2)

如果你有大量的<button>,你的第二个解决方案会有更好的性能,因为jQuery会在$(“li.tour”)上查找冒泡事件,而不是将事件处理程序附加到每个<button>正如文档所说:“委托事件的另一个优点是,当必须监视许多元素时,它们可能会有更低的开销。在其tbody中有1,000行的数据表中,此示例将处理程序附加到1,000个元素”

“请注意,对于少量元素,尤其是复杂的选择器,在委托事件处理程序中进行的过滤在很多情况下可能比仅附加四个单独的事件处理程序慢” - adeneo < / p>

This fiddle here helps explain the difference.

<强> TL; DR

如果要选择大量元素,请使用委派的事件处理程序。

如果您有一个复杂的选择器而没有很多要选择的元素,请使用常规事件处理程序。

否则,你使用哪一个并不是什么大事。

答案 1 :(得分:2)

正如其他人所指出的那样,两种解决方案都不能与其他解决方案区别开来,因为两者都会将事件处理程序附加到3个元素(无论是li.tour还是button.book

真的利用事件冒泡,你想要做的是;

$(document).ready(function(){
  $("ul").on("click", "button.book", function(){
    var tour = $(this).closest(".tour");
    var discount = tour.data("discount");
    var message = $("<span>Call 1-555-jquery-air for a $" + discount + "</span>");
    tour.append(message);
    $(this).remove();
  });
});

...这样,只有1个事件处理程序绑定到ulEvent bubbling意味着button上的点击最终会被ul触发,这就是jQuery知道点击事件发生的原因。

这里的优点是你:

  • 不会循环3个元素(仅1个)。
  • 您的DOM只绑定了1个事件处理程序,而不是3

......显然现在这将是一个可以忽略不计(几乎不存在)的好处,但随着所涉及的元素数量的增加而增长。

一个小缺点是对ul的后代的任何点击也会冒泡到ul,让jQuery决定(因此性能很小)是否要调用点击处理程序

相关问题