jQuery 中的 addClass 和 removeClass - 不删除类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18986623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
addClass and removeClass in jQuery - not removing class
提问by rhinoceros1
I'm trying to do something very simple. Basically I have a clickable div 'hot spot', when you click that it fills the screen and displays some content. I achieved this by simply changing the class of div, removing 'spot' and adding 'grown' and there's a little CSS animation to make it grow. This works fine.
我正在尝试做一些非常简单的事情。基本上我有一个可点击的 div '热点',当你点击它时,它会填满屏幕并显示一些内容。我通过简单地改变 div 的类,删除“spot”并添加“grown”来实现这一点,并且有一些 CSS 动画可以让它增长。这工作正常。
The problem is, within this div there is a close_button, which at the moment is just text. I want this to switch the classes back - i.e. remove grown and readd spot. It doesn't do this when clicked. I believe it's to do with the element not having those classes when the DOM loads, but I'm new to jQuery and don't know how to work around this.
问题是,在这个 div 中有一个 close_button,目前只是文本。我希望这能将类切换回来 - 即删除增长和读取的点。单击时不会执行此操作。我相信这与 DOM 加载时没有这些类的元素有关,但我是 jQuery 新手,不知道如何解决这个问题。
I think there's probably a much more sensible way of doing it, could someone point me in the right direction? I'd be very grateful. I've tried using toggleClass instead to no avail.
我认为可能有更明智的做法,有人能指出我正确的方向吗?我会很感激。我试过使用 toggleClass 代替,但无济于事。
$( document ).ready(function() {
$(".clickable").click(function() {
$(this).addClass("grown");
$(this).removeClass("spot");
});
$(".close_button").click(function() {
alert (this);
$("#spot1").removeClass("grown");
$("#spot1").addClass("spot");
});
});
UPDATE:
更新:
I am using this code now,
我现在正在使用此代码,
$( document ).ready(function() {
$(document).on("click", ".close_button", function () {
alert ("oi");
$("#spot1").addClass("spot");
$("#spot1").removeClass("grown");
});
$(document).on("click", ".clickable", function () {
if ($(this).hasClass("spot")){
$(this).addClass("grown");
$(this).removeClass("spot");
}
});
});
strangely the close_button function still won't add 'spot' or remove 'grown' though it will add any other classes and it will remove other classes... I added the if clause because I thought perhaps both function were being triggered at the same time, undoing each other, but it seems to make no difference
奇怪的是,close_button 函数仍然不会添加“spot”或删除“grown”,尽管它会添加任何其他类并且会删除其他类......我添加了 if 子句,因为我认为这两个函数可能同时被触发时间,相互抵消,但似乎没有什么区别
回答by Guilherme Sehn
What happens is that your close button is placed inside your .clickable
div, so the click event will be triggered in both elements.
发生的情况是您的关闭按钮放置在您的.clickable
div 内,因此将在两个元素中触发 click 事件。
The event bubbling will make the click event propagate from the child nodes to their parents. So your .close_button
callback will be executed first, and when .clickable
is reached, it will toggle the classes again. As this run very fast you can't notice the two events happened.
事件冒泡将使点击事件从子节点传播到它们的父节点。所以你的.close_button
回调将首先执行,当.clickable
达到时,它会再次切换类。由于此运行速度非常快,您不会注意到发生了两个事件。
/ \
--------------------| |-----------------
| .clickable | | |
| ----------------| |----------- |
| | .close_button | | | |
| ------------------------------ |
| event bubbling |
----------------------------------------
To prevent your event from reaching .clickable
, you need to add the event parameter to your callback function and then call the stopPropagation
method on it.
为了防止您的事件到达.clickable
,您需要将事件参数添加到您的回调函数中,然后stopPropagation
在其上调用该方法。
$(".close_button").click(function (e) {
$("#spot1").addClass("spot");
$("#spot1").removeClass("grown");
e.stopPropagation();
});
Fiddle: http://jsfiddle.net/u4GCk/1/
小提琴:http: //jsfiddle.net/u4GCk/1/
More info about event order in general: http://www.quirksmode.org/js/events_order.html(that's where I picked that pretty ASCII art =])
有关事件顺序的更多信息:http: //www.quirksmode.org/js/events_order.html(我在那里选择了漂亮的 ASCII 艺术 =])
回答by Selvakumar Arumugam
The issue is caused because of event bubbling. The first part of your code to add .grown
works fine.
该问题是由于事件冒泡引起的。要添加的代码的第一部分.grown
工作正常。
The second part "removing grown class" on clicking the link doesn't work as expected as both the handler for .close_button
and .clickable
are executed. So it removes and readd the grown
class to the div
.
第二部分上点击链接“删除成长类”并不像预期的那样既处理工作.close_button
和.clickable
执行。所以它删除并将grown
类读取到div
.
You can avoid this by using e.stopPropagation()
inside .close_button
click handler to avoid the event from bubbling.
您可以通过使用e.stopPropagation()
内部.close_button
单击处理程序来避免这种情况,以避免事件冒泡。
DEMO:http://jsfiddle.net/vL8DP/
演示:http : //jsfiddle.net/vL8DP/
Full Code
完整代码
$(document).on('click', '.clickable', function () {
$(this).addClass('grown').removeClass('spot');
}).on('click', '.close_button', function (e) {
e.stopPropagation();
$(this).closest('.clickable').removeClass('grown').addClass('spot');
});
回答by Blake Plumb
Whenever I see addClass
and removeClass
I think why not just use toggleClass
. In this case we can remove the .clickable
class to avoid event bubbling, and to avoid the event from being fired on everything we click inside of the .clickable
div
.
每当我看到addClass
并且removeClass
我想为什么不直接使用toggleClass
. 在这种情况下,我们可以删除.clickable
该类以避免事件冒泡,并避免我们在.clickable
div
.
$(document).on("click", ".close_button", function () {
$(this).closest(".grown").toggleClass("spot grown clickable");
});
$(document).on("click", ".clickable", function () {
$(this).toggleClass("spot grown clickable");
});
I also recommend a parent wrapper for your .clickable
divs
instead of using the document
. I am not sure how you are adding them dynamically so didn't want to assume your layout for you.
我还建议您.clickable
divs
使用父包装器,而不是使用document
. 我不确定你是如何动态添加它们的,所以不想为你假设你的布局。
http://jsfiddle.net/bplumb/ECQg5/2/
http://jsfiddle.net/bplumb/ECQg5/2/
Happy Coding :)
快乐编码:)
回答by Mensur Gri?evi?
I would recomend to cache the jQuery objects you use more than once. For Instance:
我建议缓存您多次使用的 jQuery 对象。例如:
$(document).on("click", ".clickable", function () {
$(this).addClass("grown");
$(this).removeClass("spot");
});
would be:
将是:
var doc = $(document);
doc.on('click', '.clickable', function(){
var currentClickedObject = $(this);
currentClickedObject.addClass('grown');
currentClickedObject.removeClass('spot');
});
its actually more code, BUT it is muuuuuuch faster because you dont have to "walk" through the whole jQuery library in order to get the $(this) object.
它实际上更多的代码,但它更快,因为您不必“遍历”整个 jQuery 库来获取 $(this) 对象。
回答by thomasstephn
I think you're almost there.
The thing is, your $(this)
in the "close button" listener is not the clickable div. So you want to search it first. try to replace $(this)
with $(this).closest(".clickable")
. And don't forget the e.stopPropagation()
as Guilherme is suggesting. that should be something like:
我想你快到了。问题是,您$(this)
在“关闭按钮”侦听器中不是可点击的 div。所以你想先搜索它。尝试替换$(this)
为$(this).closest(".clickable")
. 并且不要忘记e.stopPropagation()
Guilherme 所建议的。那应该是这样的:
$( document ).ready(function() {
$(document).on("click", ".close_button", function () {
alert ("oi");
e.stopPropagation()
$(this).closest(".clickable").addClass("spot");
$(this).closest(".clickable").removeClass("grown");
});
$(document).on("click", ".clickable", function () {
if ($(this).hasClass("spot")){
$(this).addClass("grown");
$(this).removeClass("spot");
}
});
});
回答by lefoy
Try this :
尝试这个 :
$('.close-button').on('click', function(){
$('.element').removeClass('grown');
$('.element').addClass('spot');
});
$('.element').on('click', function(){
$(this).removeClass('spot');
$(this).addClass('grown');
});
I hope I understood your question.
我希望我理解你的问题。
回答by FiLeVeR10
why not simplify it?
为什么不简化呢?
jquery
查询
$('.clickable').on('click', function() {//on parent click
$(this).removeClass('spot').addClass('grown');//use remove/add Class here because it needs to perform the same action every time, you don't want a toggle
}).children('.close_button').on('click', function(e) {//on close click
e.stopPropagation();//stops click from triggering on parent
$(this).parent().toggleClass('spot grown');//since this only appears when .grown is present, toggling will work great instead of add/remove Class and save some space
});
This way it's much easier to maintain.
这样维护起来就容易多了。
made a fiddle: http://jsfiddle.net/filever10/3SmaV/
做了一个小提琴:http: //jsfiddle.net/filever10/3SmaV/
回答by Tushar Gupta - curioustushar
Use .on()
使用.on()
you need event delegation as these classes are not present on DOM when DOM is ready.
您需要事件委托,因为当 DOM 准备好时,DOM 上不存在这些类。
$(document).on("click", ".clickable", function () {
$(this).addClass("grown");
$(this).removeClass("spot");
});
$(document).on("click", ".close_button", function () {??
$("#spot1").removeClass("grown");
$("#spot1").addClass("spot");
});??
回答by Krasimir
I think that the problem is in the nesting of the elements. Once you attach an event to the outer element the clicks on the inner elements are actually firing the same click event for the outer element. So, you actually never go to the second state. What you can do is to check the clicked element. And if it is the close button then to avoid the class changing. Here is my solution:
我认为问题在于元素的嵌套。将事件附加到外部元素后,内部元素上的点击实际上会为外部元素触发相同的点击事件。所以,你实际上永远不会进入第二个状态。您可以做的是检查单击的元素。如果是关闭按钮,则避免类更改。这是我的解决方案:
var element = $(".clickable");
var closeButton = element.find(".close_button");
var onElementClick = function(e) {
if(e.target !== closeButton[0]) {
element.removeClass("spot").addClass("grown");
element.off("click");
closeButton.on("click", onCloseClick);
}
}
var onCloseClick = function() {
element.removeClass("grown").addClass("spot");
closeButton.off("click");
element.on("click", onElementClick);
}
element.on("click", onElementClick);
In addition I'm adding and removing event handlers.
此外,我正在添加和删除事件处理程序。
JSFiddle -> http://jsfiddle.net/zmw9E/1/
JSFiddle -> http://jsfiddle.net/zmw9E/1/
回答by Zach Pedigo
I actually just resolved an issue I was having by swapping around the order that I was altering the properties in. For example I was changing the attribute first but I actually had to remove the class and add the new class before modifying the attributes. I'm not sure why it worked but it did. So something to try would be to change from $("XXXX").attr('something').removeClass( "class" ).addClass( "newClass" )
to $("XXXX").removeClass( "class" ).addClass( "newClass" ).attr('something')
.
我实际上只是通过交换更改属性的顺序解决了我遇到的问题。例如,我首先更改了属性,但实际上我必须在修改属性之前删除该类并添加新类。我不确定它为什么有效,但确实有效。因此,要尝试的方法是从 更改$("XXXX").attr('something').removeClass( "class" ).addClass( "newClass" )
为$("XXXX").removeClass( "class" ).addClass( "newClass" ).attr('something')
。