Reputation: 39028
I have 2 buttons, click one will swap classes for both buttons.
The classes are selected
and unselected
.
My CodePen:
http://codepen.io/leongaban/pen/iLBvs
For example: click the Login button will remove it's unselected class and give it its selected class and give the Register button its unselected class.
Now the problem is that the register_unselected
class doesn't work. The unselected
classes are the ones that have click actions in my jQuery.
I should be able to keep clicking the gray button and turning it blue. However after clicking the first gray button (login) the new gray button register doesn't work.
Using Chrome's inspector I can clearly see that my register_unselected class has been added, yet the click function doesn't work.
Any ideas? How would you approach this?
// Login Tab (default : first)
$(".login_unselected").click(function(){
console.log('clicked login');
// Show Login Tab as selected
$(this)
.removeClass('login_unselected')
.addClass('login_selected');
// Show Register Tab as unselected
$(this).parent().find('#tab_register')
.removeClass('register_selected')
.addClass('register_unselected');
});
// Register Tab
$(".register_unselected").click(function(){
console.log('clicked register');
// Show Login Tab as selected
$(this)
.removeClass('register_unselected')
.addClass('register_selected');
// Show Register Tab as unselected
$(this).parent().find('#tab_login')
.removeClass('login_selected')
.addClass('login_unselected');
});
Upvotes: 6
Views: 4142
Reputation: 2325
Nobody has given the more obvious and elegant solution.
Lets clean up the CSS a little:
//instead of .login_unselected, .registerunselected
.target {
color: #ccc;
background: #666;
cursor: pointer;
}
//instead of .x_selected, .y_selected
.selected {
color: #fff;
background: #3399cc;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
}
So the HTML is now
<ul>
<li id="tab_login" class="target">Login</li>
<li id="tab_register" class="target">Register</li>
</ul>
The jQuery is:
$("ul").on("click", ".target", function(){
// Remove selected class from any that have it
$(".target").removeClass('selected');
// Add class to the one you're clicking on
$(this).addClass('selected');
});
Instead of calling the class .target
you can call it .unselected
. From the context of your question it's likely that you don't need two separate classes, classes are made to be applied to many elements and if you need to reference them individually you have the id
s already.
Also remember, you can apply many classes to an element and then override styles from one class by specifying different property values on the last class. Whichever class is applied last will override the settings of any classes already applied to it, unless values for the properties you wish to override have not been specified in the overriding class.
Upvotes: 2
Reputation: 6871
You can also do this
// Login Tab (default : first)
$(".login_unselected").click(function(){
console.log('clicked login');
// Show Login Tab as selected
$(this)
.removeClass('login_unselected')
.addClass('login_selected');
// Show Register Tab as unselected
$(this).parent().find('#tab_register')
.removeClass('register_selected')
.addClass('register_unselected');
});
// Register Tab
$("#tab_register").click(function(){
console.log('clicked register');
if($(this).hasClass("register_unselected")){
// Show Login Tab as selected
$(this)
.removeClass('register_unselected')
.addClass('register_selected');
// Show Register Tab as unselected
$(this).parent().find('#tab_login')
.removeClass('login_selected')
.addClass('login_unselected');
}
});
Listen to the ID and then check is it's this class.
.on
is faster
[http://www.jsperf.com/change-class-on-click]
Upvotes: 1
Reputation: 15229
When you call $(".register_unselected").click()
jQuery actually searches the DOM for any elements matching .register_unselected
and then listens for click events on them. Since your element won't exist until after this method is called, this will have no effect.
Instead, use $("body").on("click", ".register_unselected", function(){})
;
You could also replace body
with another selector that will always contain the element changing classes.
EDIT: Here's a forked CodePen: http://codepen.io/anon/pen/DqFuL
Upvotes: 10
Reputation: 15404
Use .on()
to delegate the click events from a dom element that is static and contains both.
So, if at page-load, you have:
<ul id="container">
<li class="login_selected">Login</li>
<li class="register_unselected">Register</li>
</ul>
Then instead of using .click(), do this:
$('#container').on('click', '.login_unselected', function(){
//do stuff
});
and
$('#container').on('click', '.register_unselected', function(){
//do stuff
});
Upvotes: 1
Reputation:
When you assign the click handlers based on class, the handlers are set on the buttons that match that class AT THAT TIME. They won't change just because you've changed the classes. You need to implement a click handler that detects what classes are set at click time and act accordingly.
Upvotes: 1