I'm trying to make it so that when a li element is hovered the background-position changes (which is working great) and when clicked it stays at the second active state (not working at all). It works if in the HTML the class "active" is applied to the element already. I've tried just about everthing I can think of and searched for a long time, but can't seem to figure it out.
HTML:
<div id="navigation">
<ul>
<li><a href="#">Mission</a></li>
<li class="active"><a href="school.html">School</a></li>
<li><a href="programs.html">Programs</a></li>
<li><a href="instructors.html">Instructors</a></li>
<li><a href="contact.html">Contact Us</a></li>
<li class="bumpR"><a href="store.html">Store</a></li>
<li><a href="blog.html">Blog</a></li>
</ul>
</div> <!-- end navigation -->
jQuery:
$('#navigation li').not('li.active').mouseover(function() {
$(this).stop().animate({backgroundPosition: '0px -40px'}, 500);
// $(this).children('a').animate({opacity: .1}, 50);
$(this).children('a').css({ 'color': 'black'});
// $(this).children('a').delay(300).animate({opacity: 1}, 350);
})
$('#navigation li').not('li.active开发者_运维知识库').mouseleave(function() {
$(this).stop().animate({backgroundPosition: '0px 0'}, 250);
//$(this).children('a').animate({opacity: .1}, 25);
$(this).children('a').css({ 'color': 'white'});
// $(this).children('a').delay(150).animate({opacity: 1}, 175);
});
$('#navigation li').click(function() {
$(this).addClass("active");
});
So for example hovering over "School" will correctly not animate the background position when the mouse leaves, but while clicking "Mission" will add the class "active" the mouseleave function still runs.
Any ideas why?
.mouseleave()
binds the handler to every element in the set. At the time that the handler is bound, only one <li>
has class active
, so only that element will not have the mouseleave
handler bound.
Instead, use .live()
:
$('#navigation li:not(.active)').live('mouseleave', function ()
{
$(this)
.stop()
.animate({backgroundPosition: '0px 0'}, 250)
.children('a')
.css({ 'color': 'white'});
});
or .delegate()
:
$('#navigation').delegate('li:not(.active)', 'mouseleave', function ()
{
$(this)
.stop()
.animate({backgroundPosition: '0px 0'}, 250)
.children('a')
.css({ 'color': 'white'});
});
Edit
Fairly complete demo: http://jsfiddle.net/mattball/2mqSr/
You never remove the active
class from other elements, so they add up.
$('#navigation li').click(function() {
$('#navigation li').removeClass("active"); // remove all initially
$(this).addClass("active"); // add to the clicked one
});
Your not
condition is only evaluated at the time of declaration, not when the event fires. You'd need to check within the event method.
So what you are effectively saying is
All the li elements under the dom element with the name "navigation" that do not have the class "active" assigned to them should be bound to the mouseover and mouseleave event handlers given.
So it doesn't matter what you do after that's been done, the LIs that aren't "active" when those two instructions run will always run the mouseover and mouseleave functions given. You'll need to check for the class assignment inside the functions so that it's acted upon when the event is triggered.
It's not a case of your "School" element working correctly, it's simply not bound to the event handlers.
This is because your events are bound to your functions once.
When the code
$('#navigation li').not('li.active').mouseleave(function() { // Code });
executes, none of the <li>
s have the active class so the event is bound to all the <li>
s. You could use .live(), but a better solution would be to change your mouseleave function to look like this:
$('#navigation li').mouseleave(function() {
if($(this).hasClass('active'))
return false;
$(this).stop().animate({backgroundPosition: '0px 0'}, 250);
//$(this).children('a').animate({opacity: .1}, 25);
$(this).children('a').css({ 'color': 'white'});
// $(this).children('a').delay(150).animate({opacity: 1}, 175);
});
Since .live() has potential to be a bit slow if you have a lot of <li>
s
精彩评论