jQuery $(".class").click(); - 多个元素,点击事件仅触发一次

104

我在页面上有多个同名类(class)。我在JS中使用.click()事件。我想要的是,无论页面上有多少重复类(class),点击事件只能发生一次。

情境是我正在使用AJAX添加到购物车。有时主页上可能会显示特色产品和热门优惠,这意味着相同的类 .add .#productid# 存在,当单击添加到购物车时,AJAX会被触发两次。

我考虑过创建'点击区域',因此我将拥有.container-name .add .#pid#,从而提供唯一的点击。

这是唯一的解决方法吗?

<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>


$(".addproduct").click(function(){//do something fired 5 times});

请发布您的代码,您所说的话对我来说没有意义。 - Lazarus
是的,请发布您的JavaScript代码。 - Yngve B-Nilsen
1
它应该只触发一次,可能是您的 HTML 的问题 - 也许一个 addproduct 类被嵌套在另一个类中,或者是处理程序出现错误,在单击时触发了两次 ajax。无论哪种情况,我们都需要看更完整的代码才能确定。 - Simon
3
糟糕的提问和回答。我遇到了类似的问题,但起始帖子中没有提到解决方法或混乱的处理方式……很令人泄气,人们不能正确使用这个网站,却期望自己能成为开发者。 - ocergynohtna
使用 data-id="151",然后 $(this).data('id')。 - Andres SK
21个回答

152

很抱歉打扰了这个老帖子。我现在也遇到了同样的问题,想分享一下我的解决方案。

$(".yourButtonClass").on('click', function(event){
    event.stopPropagation();
    event.stopImmediatePropagation();
    //(... rest of your JS code)
});

event.StopPropagationevent.StopImmediatePropagation()可以解决问题。

对于事件处理程序的.class选择器会导致点击事件冒泡(有时到父元素,有时到DOM中的子元素)。

event.StopPropagation()方法确保事件不向父元素冒泡,而event.StopImmediatePropagation()方法确保事件不冒泡到所需类选择器的子元素。

来源: https://api.jquery.com/event.stoppropagation/ https://api.jquery.com/event.stopimmediatepropagation/


3
这是正确的解决方案。如果你用 jQuery 点击一个类(class),它可能会向其他元素冒泡并注册多次点击事件。阻止该点击事件传播到其他元素就是解决这个问题的方法。我认为其他一些答案误解了这里最有可能发生的事情。 - RATKNUKKL
非常感谢。我整个晚上都在寻找这个答案。这是唯一解决问题的答案。我试图为Google Maps InfoWindow的元素获取正确的“click”侦听器,该元素对于地图中的所有标记都具有相同的“.gm-style-iw-a”类。在我的情况下,只需使用“event.stopImmediatePropagation()”即可解决问题。 - Joe Hackerberg

108
$(document).on('click', '.addproduct', function () {
    // your function here
});

它能工作吗?从来没有见过像这样使用函数。 - Nabeel Khan
我应该如何从另一个事件中调用给定的答案? - Murad Hasan
1
尝试了所有方法,这是唯一有效的解决方案。 - Matt
第二个参数的解释:一个选择器字符串,用于过滤触发事件的选定元素的后代。如果选择器为null或省略,则事件总是在到达选定元素时触发。 - zwlxt

50

能否展示您的点击处理函数?您正在将5个监听器附加到5个不同的元素上。但是,当用户单击该元素时,只触发一个事件。

$(".addproduct").click(function(){
  // Holds the product ID of the clicked element
  var productId = $(this).attr('class').replace('addproduct ', '');

  addToCart(productId);
});
如果这个解决方案不起作用,我想查看你的点击处理程序。

28

当您单击具有addproduct类的div时,只会为该特定元素触发一个事件,而不是五个。如果事件被触发了5次,则您的代码存在问题。


25
我喜欢这个回答是如此明显,然后询问者说他们要检查他们的代码,好像这不是他们一开始就要做的事情一样 :D。 - KI4JGT
1
我对这个答案被接受感到惊讶。正如Ivan Kalafatić所提到的,问题在于点击事件正在传播到其他元素。解决方案是停止这种传播。请查看Ivan Kalafatić的答案以了解如何做到这一点。编辑:刚刚注意到正确的答案实际上是由Ivan Kalafatić而不是Machavity(他进行了编辑)编写的。已经纠正了我的错误。 - RATKNUKKL

17

在这种情况下,我会尝试:

$(document).on('click','.addproduct', function(){

    //your code here

 });

那么,如果你需要在点击其中一个具有相同类名的元素时在其他元素中执行某些操作,你可以通过循环遍历这些元素:

$(document).on('click','.addproduct', function(){
   $('.addproduct').each( function(){

      //your code here
     }
  );
 }
);

11

我认为您添加了五次单击事件。 尝试计算一下您这样做了几次。

console.log('add click event')
$(".addproduct").click(function(){ });

使用AngularJS时,我注意到它为了测试x次复制了脚本标签!感谢提供可能的解决方案。 - Dean Meehan

8
这将修复它并且是一个好习惯:.unbind()
$(".addproduct").unbind().click(function(){
   //do something 
});

1
请注意,unbind已被弃用(来自https://api.jquery.com/unbind):自jQuery 3.0起,.unbind()已被弃用。自jQuery 1.7以来,它已被.off()方法取代,因此其使用已经不鼓励。 - Tomer

6

我通过使用内联的 jQuery 函数来解决了这个问题,就像这样:

<input type="text" name="testfield" onClick="return testFunction(this)" /> 

<script>
  function testFunction(current){
     // your code go here
  }
</script>

你救了我的一天,伙计! - Smaïne

5

我刚遇到了同样的问题。 在我的情况下,PHP代码生成了几次相同的jQuery代码,这就是多次触发的原因。

<a href="#popraw" class="report" rel="884(PHP MULTIPLE GENERATER NUMBERS)">Popraw / Zgłoś</a>

PHP多个生成器生成相同的代码多次

<script type="text/javascript">
$('.report').click(function(){...});
</script>

我的解决方案是将脚本单独放在一个php文件中,并仅加载一次该文件。


你的评论带领我找到了解决方案 - 我也遇到了同样的问题,每个元素都会在单击时触发事件。这是因为我把脚本放在了一个被加载多次的局部视图(asp mvc)中。谢谢你。 - Hanshan

4

$(document).ready(function(){

    $(".addproduct").each(function(){
          $(this).unbind().click(function(){
               console.log('div is clicked, my content => ' + $(this).html());
           });
     });
}); 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="addproduct 151">product info 1</div>
<div class="addproduct 151">product info 2</div>
<div class="addproduct 151">product info 3</div>
<div class="addproduct 151">product info 4</div>
<div class="addproduct 151">product info 5</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接