【问题标题】:Click Triggers Event Listener That It Creates单击触发它创建的事件侦听器
【发布时间】:2022-01-28 05:53:26
【问题描述】:

在下面的示例中,为什么单击按钮不仅会触发添加到按钮的事件侦听器,还会触发添加到正文的事件侦听器?换句话说:为什么颜色会变成红色而不是绿色?以及如何防止这种情况发生?

$("button").on("click", function() {
  // Change Color
  $("body").css({
    "background-color": "#3FE1B0"
  });
  // Add New Event Listener...
  $("body").on("click", function() {
    // ...Which Also Changes Color
    $(this).css({
      "background-color": "#FF4F5E"
    });
  });
});
/* Design Changes */
body {
  height: 100vh;
  margin: 0;
  
  display: flex;
  justify-content: center;
  align-items: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>

<button>Click Me!</button>

【问题讨论】:

  • 这似乎可疑类似于我刚刚评论过的这个问题:stackoverflow.com/questions/70884929/… 但是由于某种原因,我的解决方案无法按预期工作,似乎在这里工作 -所以我要给它一个答案!

标签: javascript jquery dom-events


【解决方案1】:

你的问题是event propagation。当用户使用您的原始代码单击按钮时会发生什么:

  • 事件处理程序触发并将背景颜色更改为您指定的颜色 (#3FE1B0)
  • 事件处理程序也被添加到正文中以将颜色更改为#FF4F5E
  • 事件向上传播到其父元素,包括位于链末端的主体
  • 因此主体上的事件处理程序运行(它只是刚刚添加的事实没有任何区别),因此颜色变为您不想要的颜色

解决方法很简单:使用事件的stopPropagation 方法阻止它向上传播:

$("button").on("click", function(event) {
  // Change Color
  $("body").css({
    "background-color": "#3FE1B0"
  });
  // Add New Event Listener...
  $("body").on("click", function() {
    // ...Which Also Changes Color
    $(this).css({
      "background-color": "#FF4F5E"
    });
  });
  event.stopPropagation();
});
/* Design Changes */
body {
  height: 100vh;
  margin: 0;
  
  display: flex;
  justify-content: center;
  align-items: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>

<button>Click Me!</button>

【讨论】:

    【解决方案2】:

    问题的根源之一是单击&lt;body&gt; 内的&lt;button&gt; 会触发&lt;body&gt; 元素和&lt;button&gt; 元素的单击事件。您需要使用event.stopPropagation() 来防止事件冒泡 DOM 树。

    $("button").on("click", function(e) {
      $("body").css({ "background-color": "#3FE1B0" });
      e.stopPropagation();
    });
    
    $("body").on("click", function(e) {
        $("body").css({ "background-color": "#FF4F5E" });
    });
    body {
      height: 100vh;
      margin: 0;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    <!DOCTYPE html>
    <html>
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <title>Page Title</title>
    </head>
    <body>
      <button>Click Me!</button>
    </body>
    </html>

    【讨论】:

      【解决方案3】:

      首先,您应该重新排列代码。

      其次,使用stopPropagation 防止触发两个点击处理程序。

      试试下面的例子:

      $("body").on("click", function(e) {
        $(this).css({
          "background-color": "#FF4F5E"
        });
      });
      
      $("button").on("click", function(e) {
        e.stopPropagation()
        $("body").css({
          "background-color": "#3FE1B0"
        });
      });
      /* Design Changes */
      
      body {
        height: 100vh;
        margin: 0;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
      
      <button>Click Me!</button>

      【讨论】:

        猜你喜欢
        • 2021-10-27
        • 2022-11-04
        • 2020-09-06
        • 2015-12-18
        • 2018-11-17
        • 1970-01-01
        • 2013-05-19
        • 1970-01-01
        • 2013-06-14
        相关资源
        最近更新 更多