jQuery.on() 无法正常工作

jQuery .on() not working correctly

这很难解释...

我有一个自定义按钮。

<button class="like-post">Like Post</button>

用户点击赞后,我执行 AJAX 调用并向数据库添加一行,然后添加和删除 class。

btn.removeClass('btn-success')
          .removeClass("like-post")
          .addClass('btn-default')
          .addClass('unlike-post')
          .html("<span class='glyphicon glyphicon-remove'></span> Un-like");

一切正常,除了在 class 更改为 'unlike-post' 之后按钮仍然对类似 post class 触发器做出反应。

所以我有这个:

$(".like-post").on('click', function(){ });

即使按钮没有 class 之类的 post,它也会执行该操作。我已经检查过 class 肯定会被正确删除/添加。

我想对 unlike-post class 执行另一个操作,但在这个问题解决之前不能。

我在我网站的其他地方注意到了一个关于 .on() 的类似问题。我无法在 jsFiddle 中重现该问题,因为它在那里工作正常。

使用 bootstrap + 最新的 jQuery 版本。有任何想法吗?我知道这不太可能,但认为有人可能遇到过类似的问题。

谢谢。

问题是您将处理程序连接到元素,此后 class 是否更改都没有关系。

使用附加到不变祖先的委托处理程序:

 $(document).on("click", ".like-post", function(){ });

委托事件通过侦听事件冒泡到祖先元素来工作。然后他们在事件时间(不是事件注册时间)将 jQuery 过滤器应用于气泡链中的元素。然后,他们仅将该函数应用于引起该事件的匹配元素。这种类型的处理程序实际上可以更有效(因为它用一个更慢的事件处理程序来换取更快的设置时间)。由于点击速度非常慢,您永远不会注意到委托事件处理程序比直接连接的处理程序慢。

documentis the default if no other element is handy, but never usebody` 用于委托事件,因为它有一个错误(如果样式导致计算出的主体高度为 0,它将不会响应鼠标事件)。

尽管您通常会尝试绑定到靠近变化元素的祖先。

这是因为 .on() 在某个特定时刻计算元素,当它被定义时。它是否仍然匹配选择器并不重要。

如果您需要更灵活的解决方案,请将更多参数传递给 .on(),例如:

$("body").on("click", ".like-post", function () {});

这样,目前只有 like-post class 的元素才会被匹配。

它不需要是 body,它可以是你知道的最深的元素,它总是包含这个 .like-post 按钮。

我猜问题出在on的定义上。 (参见 http://api.jquery.com/on/

"on"实际上有两种工作方式。

$( ".like-post" ).on( "click", function() {
});

对比

$( "body" ).on( "click", ".like-post", function() {
});

第一个基本意思是:

将函数绑定到所有 "life-post" 当前为 class 的元素上,并在点击发生时执行。

第二个是:当点击事件在"body"内发生在具有class"like-post"的元素上时执行函数。

主要区别在于第一种情况在代码第一次执行时绑定在"current state"个元素上(意思是绑定代码),而第二种情况反映了dom个元素的状态当 "click" 动作发生时。

您可以使用 $(document) 或其他选择器来代替 body,但基本上您必须避免直接使用该元素,而是使用它的父元素。

或者您也可以像这样检查:

$( ".like-post" ).on( "click", function() {
   // the class has been removed
   if(!$(this).hasClass("like-post))
      return;

   ......
});

当您直接向元素添加事件时,它不会在您更改 class 时神奇地删除事件。您需要取消绑定它或在函数内部添加逻辑。另一种选择是使用事件委托

解绑示例:

$(".like-post").on('click', function(){ 
    $(this).unbind("click");
    //logic here
});

支票的基本思路:

$(".like-post").on('click', function(){ 
    var btn = $(this);
    if (btn.hasClass("xxx")) {
        //do this logic
    } else {
        //do that logic
    }
});

事件委托:

$(document).on("click", ".like-post", function(){ console.log("like clicked" });