addClass and removeClass in jQuery - not removing class

后端 未结 10 1576
不知归路
不知归路 2020-12-05 02:02

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

相关标签:
10条回答
  • 2020-12-05 02:42

    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.

    $(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.

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

    Happy Coding :)

    0 讨论(0)
  • 2020-12-05 02:52

    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.

    0 讨论(0)
  • 2020-12-05 02:53

    What happens is that your close button is placed inside your .clickable div, so the click event will be triggered in both elements.

    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.

                        / \
    --------------------| |-----------------
    | .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.

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

    Fiddle: 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 =])

    0 讨论(0)
  • 2020-12-05 02:53

    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/

    0 讨论(0)
  • 2020-12-05 02:55

    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/

    0 讨论(0)
  • 2020-12-05 02:57

    I would recomend to cache the jQuery objects you use more than once. For Instance:

        $(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.

    0 讨论(0)
提交回复
热议问题