jQuery中的addClass和removeClass - 不删除类

时间:2013-09-24 16:03:08

标签: jquery dom addclass removeclass toggleclass

我正在尝试做一些非常简单的事情。基本上我有一个可点击的div'热点',当你点击它填满屏幕并显示一些内容。我通过简单地改变div的类,删除'spot'并添加'grow'来实现这一点,并且有一些CSS动画来使它成长。这很好用。

问题是,在这个div中有一个close_button,目前只是文本。我希望这可以将类切换回来 - 即删除增长和读取的点。单击时不会执行此操作。我相信这是在DOM加载时没有这些类的元素,但我是jQuery的新手,并且不知道如何解决这个问题。

我认为这可能是一种更明智的做法,有人能指出我正确的方向吗?我会非常感激的。我尝试过使用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");
    });   
});

更新:

我现在正在使用此代码,

$( 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");
        }
    });
});

奇怪的是,close_button函数仍然不会添加'spot'或删除'grow'虽然它会添加任何其他类并且它将删除其他类...我添加了if子句因为我认为可能两个函数都被触发同时,相互撤消,但似乎没有区别

10 个答案:

答案 0 :(得分:60)

当您的关闭按钮放在.clickable div中时会发生什么,因此将在两个元素中触发click事件。

事件冒泡将使click事件从子节点传播到其父节点。因此,您的.close_button回调将首先执行,当达到.clickable时,它将再次切换类。由于运行速度非常快,您无法注意到发生的两件事。

                    / \
--------------------| |-----------------
| .clickable        | |                |
|   ----------------| |-----------     |
|   | .close_button | |          |     |
|   ------------------------------     |
|             event bubbling           |
----------------------------------------

为防止您的活动到达.clickable,您需要将事件参数添加到回调函数中,然后调用其上的stopPropagation方法。

$(".close_button").click(function (e) { 
    $("#spot1").addClass("spot");
    $("#spot1").removeClass("grown");
    e.stopPropagation();
});

小提琴:http://jsfiddle.net/u4GCk/1/

关于一般事件顺序的更多信息:http://www.quirksmode.org/js/events_order.html(我选择的那个漂亮的ASCII艺术=])

答案 1 :(得分:13)

问题是由event bubbling引起的。您添加.grown的代码的第一部分可以正常工作。

第二部分“删除已成熟的类”在单击链接时无法正常工作,因为.close_button.clickable的处理程序都已执行。因此,它会将grown类移除并读取到div

您可以在e.stopPropagation()点击处理程序中使用.close_button来避免此事件,以避免事件冒泡。

DEMO: http://jsfiddle.net/vL8DP/

完整代码

$(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');
});

答案 2 :(得分:7)

每当我看到addClassremoveClass时,我想为什么不使用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");
}); 

我还建议您使用.clickable divs的父包装,而不是使用document。我不确定你是如何动态添加它们所以不想为你假设你的布局。

http://jsfiddle.net/bplumb/ECQg5/2/

快乐编码:)

答案 3 :(得分:4)

我建议您多次缓存您使用的jQuery对象。 对于实例:

    $(document).on("click", ".clickable", function () {
        $(this).addClass("grown");
        $(this).removeClass("spot");
    });

将是:

    var doc = $(document);
    doc.on('click', '.clickable', function(){
       var currentClickedObject = $(this);
       currentClickedObject.addClass('grown');
       currentClickedObject.removeClass('spot');
    });

它实际上更多的代码,但它是muuuuuuch更快,因为你不必“遍历”整个jQuery库,以获得$(this)对象。

答案 4 :(得分:3)

我想你差不多了。 问题是,“关闭按钮”监听器中的$(this)不是可点击的div。所以你想先搜索它。尝试将$(this)替换为$(this).closest(".clickable")。并且不要忘记Guilherme建议的e.stopPropagation()。应该是这样的:

$( 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");
        }
    });
});

答案 5 :(得分:1)

试试这个:

$('.close-button').on('click', function(){
  $('.element').removeClass('grown');
  $('.element').addClass('spot');
});

$('.element').on('click', function(){
  $(this).removeClass('spot');
  $(this).addClass('grown');
});

我希望我理解你的问题。

答案 6 :(得分:1)

为什么不简化它?

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
});

这样维护起来就容易多了。

做了一个小提琴:http://jsfiddle.net/filever10/3SmaV/

答案 7 :(得分:0)

使用.on()

你需要事件委托,因为当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");
});  

答案 8 :(得分:0)

我认为问题在于元素的嵌套。将事件附加到外部元素后,内部元素的单击实际上会为外部元素触发相同的单击事件。所以,你实际上从未进入过第二个州。你可以做的是检查点击的元素。如果是关闭按钮则避免课程改变。这是我的解决方案:

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);

此外,我正在添加和删除事件处理程序。

JSFiddle - > http://jsfiddle.net/zmw9E/1/

答案 9 :(得分:0)

我实际上通过交换更改属性的顺序解决了我遇到的一个问题。例如,我先更改属性,但实际上我必须先删除该类并添加新类,然后再修改属性。我不确定为什么会奏效,但确实奏效了。因此,可以尝试将$("XXXX").attr('something').removeClass( "class" ).addClass( "newClass" )更改为$("XXXX").removeClass( "class" ).addClass( "newClass" ).attr('something')