【问题标题】:addClass and removeClass in jQuery - not removing classjQuery 中的 addClass 和 removeClass - 不删除类
【发布时间】:2013-09-29 23:09:45
【问题描述】:

我正在尝试做一些非常简单的事情。基本上我有一个可点击的 div '热点',当你点击它时,它会填满屏幕并显示一些内容。我通过简单地更改 div 的类、删除“spot”并添加“grown”来实现这一点,并且有一些 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' 或删除 'grown',尽管它会添加任何其他类并且会删除其他类...我添加了 if 子句,因为我认为这两个函数可能都被触发了同时,相互撤销,但似乎没有区别

【问题讨论】:

  • 你能给我们看看你的html吗?使用此代码,您可以在 .close_button 元素上添加和删除类。
  • 发布于 14 年 1 月 20 日

    孟加拉国

    故事标题

    Egestas eros ac risus faucibusr

    关闭
  • 我看到了一个相同的属性。当我交换我的 "$(this).removeClass("spot");" 版本时对于 "$(this).removeAttr("class");"它会删除除现场之外的所有课程 - 真气。
  • 是否有其他函数可以将类添加或分配给这些元素或包含它们的元素范围?

标签: jquery dom addclass removeclass toggleclass


【解决方案1】:

发生的情况是您的关闭按钮被放置在您的.clickable div 中,因此点击事件将在两个元素中触发。

事件冒泡将使点击事件从子节点传播到其父节点。所以你的.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 艺术 =])

【讨论】:

  • 为了完成,实际上有几种方法可以防止事件冒泡,每种方法都有自己的微妙之处。例如,return false 不仅会停止传播,还会停止默认操作。看到这个article for further reference。
【解决方案2】:

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

单击链接时的第二部分“删除成长类”无法按预期工作,因为 .close_button 和 .clickable 的处理程序都已执行。所以它删除了grown 类并将其读取到div。

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

演示: 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');
});

【讨论】:

    【解决方案3】:

    每当我看到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");
    }); 
    

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

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

    快乐编码:)

    【讨论】:

      【解决方案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');
          });
      

      实际上它的代码更多,但速度更快,因为您不必“遍历”整个 jQuery 库来获取 $(this) 对象。

      【讨论】:

        【解决方案5】:

        我想你快到了。 问题是,“关闭按钮”侦听器中的 $(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");
                }
            });
        });
        

        【讨论】:

          【解决方案6】:

          使用.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");
          });  
          

          【讨论】:

          • 我之前试过这个,真的认为它会解决问题,但它什么也没做......我发出警报以确认点击正在关闭按钮上工作,div id 肯定是正确(spot1)...
          • 我还注意到 - 我可以添加除“spot”以外的类,但不能添加“spot”!然后我想也许第一个函数与第二个函数同时被调用并且它们相互抵消,所以我添加了: $(document).on("click", ".clickable", function () { if ($(this).hasClass("spot")){ $(this).addClass("grown"); $(this).removeClass("spot"); } }); $(document).on("click", ".close_button", function () { alert ("oi"); $("#spot1").addClass("spot"); $("#spot1"). removeClass("成长"); }); ...无济于事
          【解决方案7】:

          试试这个:

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

          希望我能理解你的问题。

          【讨论】:

            【解决方案8】:

            为什么不简化呢?

            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/

            【讨论】:

              【解决方案9】:

              我认为问题在于元素的嵌套。将事件附加到外部元素后,对内部元素的点击实际上会为外部元素触发相同的点击事件。所以,你实际上永远不会进入第二种状态。您可以做的是检查单击的元素。如果是关闭按钮,则避免更改类。这是我的解决方案:

              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/

              【讨论】:

                【解决方案10】:

                我实际上只是通过交换更改属性的顺序解决了我遇到的问题。例如,我首先更改了属性,但实际上我必须在修改属性之前删除类并添加新类.我不确定它为什么起作用,但确实起作用了。因此,可以尝试将$("XXXX").attr('something').removeClass( "class" ).addClass( "newClass" ) 更改为$("XXXX").removeClass( "class" ).addClass( "newClass" ).attr('something')。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-03-02
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-02-18
                  • 1970-01-01
                  相关资源
                  最近更新 更多