Reputation: 6547
I find my self doing this a lot:
$(document).on("click","li",function(){
$(".selected").removeClass("selected"); // Remove any old selected
$(this).addClass("selected"); // Apply selected to this element
});
Is there a better and less repetitive way of doing a task like this? Like toggle a class. Btw, only one element can be selected at a given time.
Thanks.
Upvotes: 5
Views: 167
Reputation: 6131
After debating with Jack I propose mine. Assuming your list is here :
var $myList = $('#list');
Then:
$myList.on("click","li",function(){
$(".selected",$myList).removeClass("selected"); // Remove any old selected
$(this).addClass("selected"); // Apply selected to this element
});
or
$myList.on("click","li",function(){
$(this).siblings(".selected").removeClass("selected"); // Remove any old selected
$(this).addClass("selected"); // Apply selected to this element
});
Your way of doing it is good enough for me but Jack's is faster and mine is in between both.
I like this one because you don't need to assume there will only be one selected
element. And searching is faster when we provide context as far as I know
Upvotes: 1
Reputation:
The notion of keeping track of the current element is the same as the other answers, but you can wrap this logic up cleanly in a function such as
function class_swapper=function(cls){
var cur;
return function(elt){
if (cur) { cur.classList.remove(cls); }
elt.classList.add(cls);
cur=elt;
};
};
A call to class_swapper
returns a function used to actually apply the specified class to a particular element (and remove it from the previous one, which is remembered inside the function). You can use this as follows:
var swapper=class_swapper("selected");
swapper(elt1);
swapper(elt2);
or in terms of your example
$(document).on("click","li",function(){swapper(this);});
I've used classList.add
and classList.remove
, which is a classy way (ouch) of manipulating classes in modern browsers, but of course these could be replaced by jQuery's addClass
etc. as necessary.
Upvotes: 1
Reputation: 173552
A more efficient way is to keep track of the last selected item:
var $selected = null;
$(document).on("click", "li", function() {
if ($selected) {
$selected.removeClass('selected');
}
$selected = $(this).addClass('selected');
});
Of course, this should work as long as that particular function is the only one that will ever add / remove the selected
class.
This could optionally be wrapped inside a closure to remove the $selected
variable.
Btw, using document
as the anchor for your delegation isn't best practice. It's better to choose the nearest node that will not get removed from the document.
Update
As Kevin B has mentioned, you could eliminate the branch like so:
var $selected = $();
$(document).on("click", "li", function() {
$selected.removeClass('selected');
$selected = $(this).addClass('selected');
});
The ability to use $()
was introduced in 1.4; before that you would use $([])
.
Upvotes: 6
Reputation: 9167
Thinking about this, you could keep your list elements in a variable, such as:
var $liElements = $('#yourContainer > li');
$(document).on("click","li",function(){
$liElements.not($(this)).removeClass("selected");
$(this).addClass("selected");
});
Upvotes: 1
Reputation: 2206
You can do this:
<script>
$(document).ready(function(){
$(this).on("click", "li", function() {
$(this).addClass('selected').siblings().removeClass('selected');
});
});
</script>
Upvotes: 2