Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Toggle between selected classes

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.

like image 565
Kivylius Avatar asked May 15 '13 15:05

Kivylius


4 Answers

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 $([]).

like image 151
Ja͢ck Avatar answered Nov 07 '22 23:11

Ja͢ck


You can do this:

<script>
  $(document).ready(function(){
     $(this).on("click", "li", function() {
        $(this).addClass('selected').siblings().removeClass('selected');
     });
  });
</script>
like image 40
edonbajrami Avatar answered Nov 08 '22 00:11

edonbajrami


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

like image 1
TecHunter Avatar answered Nov 08 '22 00:11

TecHunter


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");
});
like image 1
Chris Dixon Avatar answered Nov 08 '22 00:11

Chris Dixon