tags:

views:

119

answers:

4

Hi,

I'm researching the optimising of JQuery code and was wondering if there is a way to better this code as it seems quite long...

$("#tabs-nav li a").hover(

     function(){
      if($(this).parent().hasClass('active')) {
      } else {
       $(this).stop().animate({ opacity: 1, marginTop: '24px'}, 200);
      }   
     },
     function(){
      if($(this).parent().hasClass('active')) {
      } else {
       $(this).stop().animate({ opacity: 0.4, marginTop: '29px'}, 200);
      }
     }
    );

Many thanks in advance!

A: 
$(".active #tabs-nav li a")...

Just use the selector to see if the parent is active and don't use the if statements. Though if ancestors of the parent are active it will select that also. So it depends on your case.

Dennis Baker
Why is this upvoted? This is the wrong selector...
Paolo Bergantino
In his code, he's wanting to check that the immediate parent is does not have class "active", so this won't work. This is saying that in between the ".active" and the <a> element, there would be a #tabs-nav and an li, which means that it couldn't be the immediate parent. In short, this won't work.
TM
+2  A: 

You can eliminate your conditionals by passing a filter to the parent function:

$('#tabs-nav li a').hover(function() {
    $(this).parent(':not(.active)').children('#tabs-nav li a').stop().animate({ opacity: 1, marginTop: '24px'}, 200);
}, function() {
    $(this).parent(':not(.active)').children('#tabs-nav li a').stop().animate({ opacity: 0.4, marginTop: '29px'}, 200);
});

If your <a> elements are immediate children of the <li> elements, you should use Josh's solution.

TM
i don't think you can do that because the triggering element (A) is the one that has the animate() called upon, not its parent.
pixeline
You are correct, I misread it. I will fix the code :o
TM
Won't this animate all children, if there are any?
Adam Luter
@Adam, yes, I made an assumption of one item per <li> (which I think is fair considering that is the semantic meaning of a list). If he has multiple links per list item, then it would animate all the ones that exist in that same list item. I would hope that the HTML is not formatted this way, but you make a valid point.
TM
Brilliant. That works a treat!
Model Reject
A: 

i just rewrite one, you'll get the idea:

 function(){
                if($(this).parent(':not(".active")')) {
                        $(this).stop().animate({ opacity: 1, marginTop: '24px'}, 200);
                }   
        }
pixeline
why is this down voted? it works, is readable and efficient. The above-mentioned selector is heavy on Sizzle (jquery selector engine). besides, it would require live() or livequery() to work at all time.
pixeline
Not sure why, it seems workable to me :/
TM
+2  A: 
$("#tabs-nav li:not(.active) a").hover(
    function(){
        $(this).stop().animate({ opacity: 1, marginTop: '24px'}, 200);
    },
    function(){
        $(this).stop().animate({ opacity: 0.4, marginTop: '29px'}, 200);
    }
);
John Rasch
This will work perfect IF and only if the <a> element is directly under the <li> (and not just a descendant);
TM
True, I would *hope* that's the case :) - I believe you can throw in `>` i.e.: `li:not(.active) > a` - haven't tested it though
John Rasch
That would only make the first selector return nothing, if his document wasn't set up using immediate children.
TM
Won't this fail if the active class changes at runtime?
Adam Luter
@AdamLuter good point... This should be converted to a live event handler or possibly go back to doing the classname checking inside the callback.
TM
Sadly this doesn't work. the reason being that when you hover, if the li tag doesn't have a class of active, it gets added, which then renders the rolloff function void because it is only triggered if the li doesn't have class 'active.
Model Reject