【问题标题】:Event Delegation in jQuery - Which Method is Better?jQuery 中的事件委托 - 哪种方法更好?
【发布时间】:2016-10-05 15:44:26
【问题描述】:

为了编写更好的代码并改进我使用 jQuery 的方式,我最近一直在阅读。我学到的新技巧之一是在 jQuery 中使用事件委托。

在阅读时,我发现了两种“假定”不同的解决方法。下面是代码 sn-ps 来说明它们。

假设我有一个这样的 HTML 块:

<html>
  <head>
    <title>Test Code</title>
  </head>
  <body>
    <div id="switcher">
      <button id="button1">Button 1</button>
      <button id="button2">Button 1</button>
      <button id="button3">Button 2</button>
      <button id="button4">Button 3</button>
      <button id="button5">Button 4</button>
      <button id="button5">Button 5</button>
      <button id="button6">Button 6</button>
      <button id="button7">Button 7</button>
      <button id="button8">Button 8</button>
      <button id="button9">Button 9</button>
    </div>
<!-- rest of code here -->
  </body>
</html>

点击后,我想:

  1. 检索单击按钮的 ID(用于进一步操作)。
  2. 将任何按钮的类切换为“活动”。

不要这样做:

$('#switcher').find('button').click(function(){
  var $element = $(this);      
  var elementid = this.id;
  $element.toggleClass('clicked');
  //rest of code here
});

我可以这样做(方法 1)

$('#switcher').click(function(eventName){
  if ($(eventName.target).is('button')) {
    var $element =$(eventName.target);
    var elementid = eventName.target.id;
    $element.toggleClass('active');
    //rest of code here
  }
});

或者这个(方法二)

$('#switcher').on('click', 'button', function(){
  var $element = $(this);
  var elementid = this.id;
  $element.toggleClass('active');
  //rest of code here
});
  1. 这两种实际上都是委托技术吗?
  2. 如果是这样,这两种方法中哪一种更快(或性能更好)并且可以更好地处理委托?
  3. 是否存在浏览器限制?

【问题讨论】:

  • 您绝对应该让 jQuery 为您处理委托。比$(eventName.target).is('button')更复杂
  • 当然,这两种方法的作用相同:将事件处理程序附加到单个元素。但我不会仅仅为了一个微不足道的性能优势而跳过 jQuery 语法糖。无论如何,这是个好问题。
  • 我更喜欢方法 2。
  • 方法 1 和 2 是不同的,#1 不处理按钮包含其他元素的情况(这不是你的情况,但它可能是......)。正确的检查应该是if ($(eventName.target).closest('button').length)。而关于单击事件,关于性能的唯一关注点应该是可维护性的时间。速度表现在这里没有意义
  • @demo 你的例子不是事件委托..

标签: javascript jquery performance dom event-delegation


【解决方案1】:

在您非常具体的情况下,当单击 button 元素(在所有浏览器上)时,这两种方法将提供完全相同的功能,并且性能将相同(因为它是一个单击事件,所以它会很小差异,也很难以准确的方式进行测试)。

这适用于您的特定结构:

<div id="switcher">
      <button id="button1">Button 1</button>
      <button id="button3">Button 2</button>
</div>

但如果 DOM 结构发生变化,只是一点点:

<div id="switcher">       
    <button id="button1">
        <div class="inner">Button 1</div>
    </button>
    <button id="button3">
        <div class="inner">Button 2</div>
    </button>
</div>

...然后只有“官方”jQuery 事件委托实际上会检测所有子级的点击事件。

如果你已经在你的页面中使用了 jQuery,那么修改事件监听器来模拟事件委托是没有用的。除了编写更多代码之外,您不会获得任何优势。有人提到性能:用点击事件忘记它。无用的优化至少和过早的优化一样糟糕,因为它会浪费你的时间并降低代码的可读性,但在这种情况下,它甚至不是优化(或者它只是一个可以认真证明的极客游戏)。

请注意,点击事件很少(或从不?)代表性能问题。它们只偶尔发生一次。 RequestAnimationFrame、滚动或调整大小可以代表一个问题,而不是点击。点击事件可能是性能问题的唯一情况是,如果您有一个疯狂(非常极端!)复杂的 DOM 结构:但在这种情况下,这可能意味着您应该首先修复它。

【讨论】:

  • 实际上,除了已更正的代码中的小错误之外,这两种方法都适用于您提供的示例。 .target in if($(eventName.target).is('button')) { 获取执行单击操作的确切元素,无论它是否被任何元素嵌套。只要它在&lt;div id="switcher"&gt;下。
  • 对不起,我的第一个例子实际上有点错误。我修好了它。如果button 中有一个元素,那么只有第二种方法(jquery 事件委托)才能真正起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多