1

我有类似的东西:

function init(){
  $('.btn').click(function(){
    //do something;
  }
}

当通过 ajax 添加新内容时,我正在调用init(),以便单击事件适用于新按钮。但是当我单击它一次时,它会捕获几次单击(与我调用的次数一样多init())。这是有道理的,但如何避免呢?

jsFiddle 链接:http: //jsfiddle.net/s2ZAz/8/


解决方案:
* 使用 $.delegate() - http://api.jquery.com/delegate/
* 使用 $.live() - http://api.jquery.com/live/

不太受欢迎,但仍然是解决方案:
* 使用 $.off() - http://api.jquery.com/off/或 $.unbind() - http://api.jquery.com/unbind/

4

4 回答 4

2

您可以使用该unbind方法删除事件处理程序(off如果您使用新的 jQuery 1.7 语法来附加处理程序,则可以使用该方法)

更好的是,您可以使用该live方法为将来添加到页面并匹配给定选择器的任何元素设置事件处理程序。这样,您只需调用一次 init。

于 2011-12-04T19:09:25.290 回答
2

click说,“对于每个匹配选择器的对象,连接这个点击监听器”。您可能想要更类似于delegate“对于将匹配此选择器的每个对象,连接此侦听器”的内容。

$(document).delegate('button', 'click', function() {
});

如果您调用init两次,您仍然会得到双重回调,但通过这种方式,您不必调用两次init,因为添加新对象时,它们已经被分配给点击侦听器。

请注意,document根据下面 Greg 的评论,上面应该替换为最近的持久祖先。

演示

从 jQuery 1.7 开始,您可以最好使用.on()函数来实现相同的效果。

演示

于 2011-12-04T19:10:08.160 回答
1
$("body").delegate("button", "click", function() {
    alert('I\'m annoying!');
});

$('div').append("<button>Click me, I will alert twice</button><br/>");

$('div').append("<button>Click me, I will alert once</button><br/>");

$('div').append("<button>Click me, I will not alert at all</button><br/>");

试试看

于 2011-12-04T19:10:15.380 回答
0

正如大卫所提到的,并且根据 liho 的代表示例(喜欢小提琴级联警报会弹出多少次的方式!!),问题在于多个绑定,可以通过.live()(不推荐使用)或.delegate()(逐步淘汰)来解决,或.on()(首选)。但是,就性能而言,委托侦听文档甚至body节点是错误的。

一个更好的方法是确定永远不会被破坏的按钮的祖先。body是一个简单的选择,但我们几乎总是使用某种包装元素构建我们的页面,这些元素嵌套在一个或多个层次之上body,因此允许您设置更少的侦听器。

HTML:

<div id="someWrapper">
  <div class="somethingThatGetsDestroyed">
    <button>Click Me</button>
  </div>
</div>

使用 jQuery 1.7+ 的 JS:

$('#someWrapper').on('click', 'button', function() {
  alert('Clickity-click!');
});
于 2011-12-04T19:26:28.063 回答