如何防止在Jquery中多次绑定到同一个选择器?

时间:2015-03-16 16:32:35

标签: jquery

$(".post").on("click",show_hide_posts);

 //Callback function from third-party ajax plugin
 $.fn.almComplete = function(alm){

      $(".post").on("click",show_hide_posts);

 }

当document.ready我绑定点击.post。当通过ajax加载更多内容时,我使用回调函数来绑定新帖子。这使旧帖子无法正常工作。

show_hide_posts有一个简单的hasClass来检查帖子是否应该在点击时可见/隐藏。加载新帖子后,旧帖子上的hasClass检查失败,但仍适用于新帖子。

function show_hide_posts(){

e.preventDefault();

if(!$(this).hasClass('closed')){

   //hide post
   $(this).addClass("closed");

}else{

   //show post
   $(this).removeClass("closed");

}

}

我这种行为是多次同一个选择器的结果?或者我错过了其他什么?

3 个答案:

答案 0 :(得分:1)

  

我这种行为是多次同一个选择器的结果?或者我错过了其他什么?

是的,你不止一次具有约束力。

假设您有以下HTML:

<div class="posts">
  <div class="post">A</post>
  <div class="post">B</post>
</div>

你打电话

$(".post").on("click",show_hide_posts);

所以现在AB有一个点击处理程序。然后你ajax /更新html为:

<div class="posts">
  <div class="post">A</post>
  <div class="post">B</post>
  <div class="post">C</post>
  <div class="post">D</post>
</div>

并致电:

$(".post").on("click",show_hide_posts);

现在AB有两个处理程序,而CD有一个处理程序。

  

当document.ready我绑定点击.post。当通过ajax加载更多内容时,我使用回调函数来绑定新帖子。这使旧帖子无法正常工作。

正确,因此解决方案不是直接绑定到.post

$('.posts').on('click', '.post', show_hide_posts);

这适用于任意数量的动态添加帖子,.post中的所有.posts都有一个处理程序,永远不需要再次调用。

其他笔记

你很可能不应该这样做:

e.preventDefault();

这可能会导致很多问题。

您也可以替换:

if(!$(this).hasClass('closed')){
  $(this).addClass("closed");
}else{
  $(this).removeClass("closed");
}

使用:

$(this).toggleClass("closed");

答案 1 :(得分:-1)

你是对的,当一个对象已经附加时,你不应该使用范围广泛的事件处理程序。仅为新创建的对象连接单击事件,或者使用.off关闭现有对象的处理程序并使用.on

重新附加。

答案 2 :(得分:-1)

如果使用jQuery 1.7 +:

$('.post').off('click', show_hide_posts) // remove handler
          .on('click', show_hide_posts); // add handler

如果不是:

$('.post').unbind('click', show_hide_posts) // remove handler
          .bind('click', show_hide_posts); // add handler

编辑:
在我喜欢使用livequery的情况下,看看here

$('.post').livequery(function () {
    $(this).on('click', show_hide_posts);
})