Why does the live click function work automatically when it should only happen upon click?
I have a button that the user clicks(.next_1).
<a id="next_btn" class="next_1" href="#">Next</a>
After the user clicks the button, it should change the class to next_2. When the user clicks the button again, it should change it to next_3.
$('.next_1').click(function() {
$('#next_btn').removeClass('next_1').addClass('next_2');
});
$('.next_2').live('click', function() {
$('#next_btn').removeClass('next_2').addClass('next_3');
});
Currently, when the user clicks the button, it changes the class directly to next_3 when it should change it to next_2. Why does the live click function work automatically when it should only happen u开发者_高级运维pon click?
.live() in this case is the same as adding another click handler. I suggest instead using the .toggle() function.
http://api.jquery.com/toggle-event/
$('#next_btn').toggle(function() {
$('#next_btn').removeClass('next_1').addClass('next_2');
}, function() {
$('#next_btn').removeClass('next_2').addClass('next_3');
}, function() {
$('#next_btn').removeClass('next_3').addClass('next_1'); // loops back to start
});
$('#next_btn').click(function(){
if( $(this).hasClass('.next_2') ){
$(this).removeClass('next_2').addClass('next_3');
}else if( $(this).hasClass('.next_1') ){
$(this).removeClass('next_1').addClass('next_2');
}
});
If you want to stay with two separate event handlers for other reasons, I would suggest stopping the propagation of the click event and changing both to .live(). Basically, if you're going to be changing things that affect the selectors and you want those changes to be reflected in the event handlers, you either have to unbind and reset the event handlers on the new selectors or use .live():
$('.next_1').live('click', function() {
$('#next_btn').removeClass('next_1').addClass('next_2');
return(false);
});
$('.next_2').live('click', function() {
$('#next_btn').removeClass('next_2').addClass('next_3');
return(false);
});
I think the issue is that you don't stop event propagation on the first click so that click continues to bubble up to the top level. Eventually, it gets to jQuery's .live() handler and now that you've changed the class to "next_2", it matches the .live() handler and the click gets processed again. If you stop event propagation on the first click handler, then it won't get to the .live() handler when it had already been handled.
Plus, I think you're going to have to unbind the first click handler. It's bound to the specific DOM object, not to a class so it will still be handling the events even after you have changed the class name. Or, it might work to make them both .live() handlers.
If it were me, I wouldn't use two separate event handlers for one object. Just bind one event handler and add conditional logic to it based on the state.
In the interest of variety, here's another way to do it that can easily go to as many next_n levels as you want with no more code:
$('#next_btn').click(function() {
var $this = $(this);
var num = $this.data("index") || 1; // get current state
if (num < 3) { // only go up to next_3
$this.removeClass('next_' + num); // remove previous class
++num; // go up one
$this.addClass('next_' + num); // add the new class
$this.data("index", num); // store new current state
}
});
And a jsFiddle that shows it: http://jsfiddle.net/jfriend00/jpdjY/
or a more compact form:
$('#next_btn').click(function() {
var num = $(this).data("index") || 1; // get current state
if (num < 3) { // only go up to next_3
$(this).removeClass('next_' + num++).addClass('next_' + num).data("index", num);
}
});
精彩评论