简体   繁体   中英

jQuery .on() doesn't fire on click but instantly

When I click a button, I change its ID and apply a new style to it by adding a class toMenu . What I wanted to do is, when I click the button with the new ID menu , that it adds another class menuTransition . But what now happens is that it already adds the class menuTransition when I click the button with the old ID #button . But what it's supposed to do, is not add the class menuTransition until the button with the new ID #menu is clicked.
Here's my code:

$(document).ready(function() {
    $("#button").click(function(){
                $("#button").addClass("toMenu")
                $("#button").attr("id","menu");
    });
});
$(document).on("click", "#menu", function() {
        $("#menu").addClass("menuTransition");
});

What you're seeing is a bit of a race condition. With your button click event handler you're adding a class and an ID to your button. Then with your delegated event handler you're looking for any clicks on the document, even those that bubble up from descendant elements, and adding a class there as well. One way to handle this is to add a small (~ 1 msec) delay to short-circuit this race that would normally occur with your example code.

 $(document).ready(function() { $("#button").click(function() { $("#button").addClass("toMenu") setTimeout(function() { $("#button").attr("id", "menu"); }, 1) }); }); $(document).on("click", "#menu", function() { $("#menu").addClass("menuTransition"); }); 
 .toMenu { font-weight: bold; } .menuTransition { color: red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="button"> button </button> 

By adding the 1 millisecond delay, the ID is added after the click on the button has reached the document event handler, so that event handler only fires after the first click on the button.

You should not be changing the ID. Element IDs are intended to be static. You can use a class to tag the current state of the button / menu and make it behave accordingly (and at the same time avoid the inefficient delegated event handler on $(document) :

$(document).ready(function() {
    $("#menubutton").on('click', function() {
        var $this = $(this);
        if ($this.hasClass('toMenu')) {
           $this.addClass('menuTransition');
        } else {
           $this.addClass('toMenu');
        }
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM