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 use
body` 用于委托事件,因为它有一个错误(如果样式导致计算出的主体高度为 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" });
这很难解释...
我有一个自定义按钮。
<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 use
body` 用于委托事件,因为它有一个错误(如果样式导致计算出的主体高度为 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" });