简体   繁体   English

jQuery one()函数在单击时触发两次

[英]Jquery one() function fires twice on click

My Jquery one() function dies after second click instead of first click. 我的Jquery one()函数在第二次单击而不是第一次单击后死亡。 Here is my HTML 这是我的HTML

<div class="box">
  <div class="call" data-tai="5">CLICK</div>
</div>

and heres my Jquery 这是我的Jquery

$('body div').one('click', '.call', function() {
  var mother = $(this).parent();
      if(mother.css('position') === 'static') 
           mother.css('position', 'relative');

  var tai = $(this).data('tai');

  $.ajax({
      method: 'GET',
      url: '/bootstrap/call.php',
      data: 'tai='+tai,
      dataType: 'html',
      success: function(ret) {
          mother.append(ret);
      },
  });

  return false;
});

Interesting thing is, if i don't use return false; 有趣的是,如果我不使用return false; , it dies after first click. ,它会在第一次单击后死亡。 However bubbling occurs and it appends 2 html tags instead of 1, inside box element. 但是会发生bubbling ,并且会在box元素内附加2个html标签而不是1个。 Thanks for help 感谢帮助

$('body div')

would select both the divs and attach click handlers to both of them. 会同时选择两个div,并将点击处理程序都附加到它们上。 When you click on the nested div then, both clicks will be fired. 当您单击嵌套的div时,将同时触发两次单击。 Use a specific selector to avoid this. 使用特定的选择器可以避免这种情况。

$('.call')

could perhaps achieve this. 也许可以实现这一目标。

That's because event handlers bound by using .one will be fired once for each element in the jQuery collection. 这是因为使用.one绑定的事件处理程序将为jQuery集合中的每个元素触发一次 Since the return false stops the propagation of the event, if you click on the .call element, click handler of the parent element is not executed but the parent element still has an active click handler. 由于return false停止了事件的传播,因此如果单击.call元素,则不会执行父元素的单击处理程序,但是父元素仍然具有活动的单击处理程序。 You should use a more specific selector for selecting the target element. 您应该使用更具体的选择器来选择目标元素。 If the click handler should be bound to the div.call elements: 如果点击处理程序应绑定到div.call元素:

$('.box div.call').one(...);

Now, if .box elements have 9 div.call descendants then you have 9 click handlers! 现在,如果.box元素具有9个div.call后代,那么您就有9个单击处理程序! After clicking on each element jQuery unbinds the handler for that specific element. 单击每个元素后,jQuery取消绑定该特定元素的处理程序。

It's not once for all elements , it's once for each element . 不是所有元素一次 ,而是每个元素一次

If the handler should be called once for all the matching elements you can use the delegation version of the .one method: 如果应该为所有匹配的元素调用一次处理程序,则可以使用.one方法的委托版本:

$(document).one('click', '.box div.call', function() {
    // ...
});

And if you want to delegate the event and have the handler working once for dynamically generated elements you can use the .on method and :not selector: 如果要委托事件并使处理程序为动态生成的元素工作一次,则可以使用.on方法和:not选择器:

$(document).on('click', '.box .call:not(.clicked)', function() {
  $(this).addClass('clicked');
  // ...
});

Now the handler is called once for each .call element . 现在, 为每个.call元素调用一次处理程序。 Since :not excludes the elements that have .clicked class the selector doesn't match the already-clicked elements. 由于:not排除具有.clicked类的元素,因此选择器与已单击的元素不匹配。

Events bubble in JavaScript. 事件在JavaScript中冒泡。 Your code 您的密码

$('body div').one('click', '.call', function() {
}

wires up on both 都连接

<div class="box"> <!-- This -->
  <div class="call" data-tai="5">CLICK</div> <!-- And this -->
</div>

You need a more specific selector. 您需要一个更具体的选择器。 If this div is a parent element in the body like this: 如果此div是主体中的父元素,如下所示:

<body>
<div class="box">
  <div class="call" data-tai="5">CLICK</div>
</div>
<div class="box">
  <div class="call" data-tai="5">CLICK</div>
</div>
</body> 

then you can use a selector like this: 那么您可以使用如下选择器:

$('body > div').one('click', '.call', function() {
}

The question is - where do you expect your click event to be placed? 问题是-您希望将点击事件放置在哪里? Perhaps the div with the box class? 也许有box类的div?

$('div.box').one('click', '.call', function() {
}

This assumes that the .call divs are being added dynamically to the .box div. 假设.call div是动态添加到.box div中的。

PS - if you want to stop the bubbling, I suggest you pass in the event object to your click event and call stopPropagation() PS-如果您想停止冒泡,建议您将事件对象传递给click事件并调用stopPropagation()

$('div.box').one('click', '.call', function(evt) {
  evt.stopPropagation(); // no bubbling
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM