0
<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();
  });
});
4

2 回答 2

2

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

“请注意,对于少量元素,特别是对于复杂的选择器,在委托事件处理程序中发生的过滤在许多情况下可能比仅附加四个单独的事件处理程序要慢” - adeneo

这里的小提琴有助于解释差异。

TL;博士

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

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

否则,你使用哪一个没什么大不了的。

于 2013-09-07T17:22:02.613 回答
2

正如其他人所指出的那样,这两种解决方案都无法与其他解决方案区别开来,因为两者都会将事件处理程序附加到 3 个元素(无论是 ali.tour还是 a 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 个事件处理程序绑定到ul. 事件冒泡意味着在 上的点击button最终会在 上触发ul,这就是 jQuery 知道点击事件发生的方式。

这里的好处是你:

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

...显然,目前这将是一个微不足道的(几乎不存在的)好处,但会随着所涉及元素数量的增加而增长。

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

于 2013-09-07T17:46:34.163 回答