1
$('#element').children('ul').children('li').children('a').hover(function(){     
    var _this = $(this);
    _this.siblings('div').show();
},function(){
    _this.siblings('div').hide();
})

It works like it should, showing the div. but it will not hide it after. i guess _this isnt defined in the callbacl function. how do i pass it inside that function without having to select it again from the DOM? I think its a pretty basic javascript question, i just can´t figure it out.

4 Answers 4

3

You need this in both functions:

var _this = $(this);

But a little nicer way to do it is like this:

$('#element > ul > li > a').hover(function(e){ 
    $(this).siblings('div').toggle( e.type === 'mouseenter' );
});

...or if you were hoping to avoid multiple calls to .siblings(), you could do this:

$('#element > ul > li > a').each(function() {
    var $th = $(this);
    var sibs = $th.siblings('div');
    $th.hover(function(e){ 
        sibs.toggle( e.type === 'mouseenter' );
    });
});

FYI: When you do $(this), you're not selecting anything from the DOM. this is simply a direct reference to the element that is set for you when the handler is called.

Sign up to request clarification or add additional context in comments.

2 Comments

The second method looks interesting. Are there benefits? Seems like its caching all the siblings, so it doesns't have to look through the DOM on each hover, right?
@Marcel: That's right. The upside is that the selection is cached. The downside is that the overhead is greater in terms of the number of handler functions being created, and of course the elements being cached. If you have lots of siblings with not too many <a> elements, it would be fine. If you have lots of <a> elements, with not too many siblings, I'd use the first solution.
3

In your example you pass two functions as arguments to the .hover() method, so any variables you declare inside the functions, are only available within the scope of that function. So if you need to use the _this variable in the second function, you need to declare it again.

But in your case, the intermediate variable should not be necessary, and you can omit it altogether:

$('#element').children('ul').children('li').children('a').hover(function(){ 
    $(this).siblings('div').show();
} ,function(){
    $(this).siblings('div').hide();
})

6 Comments

Just pointing this out, but if you declare a variable without using var, you should be able to call it again using window.variablename - in this case window._this.
@Zydeco, while technically true, I wouldn't recommend that to my worst enemy. In effect you would give global scope to a variable named _this, which would have no contextful meaning outside the hover handler. Ugh.
I wouldn't even use _this at all, but saying that any variable that you declare inside a function only stays in that function, with no way to use it outside, is untrue.
To be semantically precise, this is a variable declaration: var x;, and this is an assignment: x = 1. Now in JavaScript you can assign a previously-undeclared variable, which automatically receives global scope. But the claim that a variable declared inside a function is always privately scoped is untrue, is in fact untrue :)
I wasn't aware we were arguing semantics, or attempting to be precise at all, since that's usually a lost cause to people that just want to know what functionality works, but I'm sure I speak for everyone who cares about that when I say thanks. Including myself, that is, since I obviously know less than you do about that kind of thing. :)
|
0

Why don't you use mouseenter and mouseleave?

Or maybe:

$('#element').children('ul').children('li').children('a').hover(function(){ 

    var _this = $(this);
    _this.siblings('div').show();

},function(){

    var _this = $(this);
    _this.siblings('div').hide();
})

The _this is "private" if i'm not mistaking in the first function statement...

2 Comments

I don't know exactly how "hover" works but if it uses mouseover then it is called everytime your mouse moves over the element.
Actually.. just checked. it's the same as using mouseenter and mouseleave. So stick to your function but remember to declare _this in both of the functions.
0

If all of your links inside #element are inside li, you can call them using $('#element > a').hover().

Try this:

$('#element > a').mouseover(function () { $(this).siblings('div').show(); }).mouseout(function () { $(this).siblings('div').hide(); });

2 Comments

I did this only for performance reasons. stackoverflow.com/questions/3177763/…
Understandable, but for clarity of code I'd have to stick with $('#element > a') as the performance boost you'd get by using the code as you have it now seems negligible at best. Unless of course you have so many div you're calling with that that it does in fact slow it down notably. But then you have other issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.