Dann
Dann

Reputation: 117

Change list-style onclick with JavaScript

I'm trying to change the style of a list element on click to have a black background with white text. When I click another one, I want it to return to its base state of a white background and black text. The problem I'm having is when I click the second list element, the first one retains the style generated in the JS. This is not what I want.

Here's the HTML:

<ul class="menu">
    <li>
        <a href="#">Item One</a>
    </li>
    <li>
        <a href="#">Item Two</a>
    </li>
</ul>

And here's the JS

$('.menu > li > a').click(function(){
    $(this).css({
        'background-color': 'black', 
        'color': 'white'
    });
    $(this).siblings('.menu > li > a').css({
        'background-color': 'white', 
        'color':'black'
    });
});

I know I'm probably just targeting the wrong thing and I've tried multiple ways, but I can't seem to figure it out. I think I have the parent, children, and sibling tree mixed up too. Any help is greatly appreciated!

Here it is on JSFiddle

Upvotes: 0

Views: 4103

Answers (4)

PSL
PSL

Reputation: 123739

Your selector is incorrect try:

$(this).closest('li').siblings().find('> a').css({
    'background-color': 'white', 
    'color': 'black'
});

or rather chain it through.

 $(this).css({
        'background-color': 'black', 
        'color': 'white'
    }).closest('li').siblings().find('> a').css({
        'background-color': 'white', 
        'color': 'black'
    });

Fiddle

In your code when you do $(this).siblings('.menu > li > a') where this is anchor tag there are no siblings with .menu class. Instead you want to go to the siblings of its parent and reset anchor tags of their direct descendants.

SInce you are setting the styles on the element, it takes priority over the css property that you have defined for hover. SO switch back to class and try this:

CSS

.menu li > a.active{
    background-color: #000; 
    color: #fff;    
}

JS

$('.menu li > a').click(function(){
    $(this).addClass('active').closest('li').siblings().find('> a.active').removeClass('active');
});

Or just

$('.menu li > a').click(function(){
    var $this =  $(this);
    $this.closest('.menu').find('a.active').not($this.addClass('active')).removeClass('active');
})

Fiddle

Upvotes: 4

Deryck
Deryck

Reputation: 7658

This will accomplish your goal and will also de-select (revert to base colors) a row if it's clicked again after being selected.

jQuery:

$('.menu li > a').click(function() {

    if($(this).hasClass('active') == true) {
        $(this).removeClass('active');
    }
    else {
        $('li > a.active').removeClass('active');
        $(this).addClass('active');
    }
});

CSS:

.menu li a {
    background-color: #FFF;
    color: #000;
}
.menu li a.active {
    background-color: #000;
    color: #FFF;
}
.menu li a:hover {
    background-color: #000;
    color: #FFF;
}

Cheers - Fiddle (sry i borrowed part of @PSL fiddle)

Upvotes: 1

chopper
chopper

Reputation: 6709

See this working jsFiddle

$('.menu li a').click(function(){
    $(this).css({
        'background-color': 'black', 
        'color': 'white'
    });
    $(this).parent().siblings().find('a').css({
        'background-color': 'white', 
        'color': 'black'
    });
});

Upvotes: 0

ssilas777
ssilas777

Reputation: 9754

Try this

$('.menu li > a').click(function(){  
    $('.menu li > a').css({
        'background-color': 'white', 
        'color': 'black'
    });
      $(this).css({
        'background-color': 'black', 
        'color': 'white'
    });
});

Upvotes: 0

Related Questions