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.

Björn
  • 12,587
  • 12
  • 51
  • 70

4 Answers4

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();
})
jevakallio
  • 35,324
  • 3
  • 105
  • 112
  • 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 Feb 20 '11 at 22:33
  • @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. – jevakallio Feb 20 '11 at 22:36
  • 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. – Zydeco Feb 20 '11 at 22:40
  • 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 :) – jevakallio Feb 20 '11 at 22:48
  • 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. :) – Zydeco Feb 21 '11 at 07:03
  • It is! I honestly just started getting into jQuery (and javascript in general) about . . . two weeks ago? I've got to say I know I'm late in the game but I never had much of an excuse to work with it before now (I've been mainly CSS/PHP/mySQL oriented). It's really quite fun, AJAX is simply awesome, and if it wasn't for my single question that I can't get answered I'd say the whole thing was a complete blast. :) – Zydeco Feb 23 '11 at 04:02
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.

user113716
  • 318,772
  • 63
  • 451
  • 440
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...

Ciprian Mocanu
  • 2,166
  • 3
  • 25
  • 44
  • I don't know exactly how "hover" works but if it uses mouseover then it is called everytime your mouse moves over the element. – Ciprian Mocanu Feb 20 '11 at 21:40
  • 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. – Ciprian Mocanu Feb 20 '11 at 21:41
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(); });

Zydeco
  • 530
  • 1
  • 5
  • 11
  • I did this only for performance reasons. http://stackoverflow.com/questions/3177763/what-is-the-fastest-method-for-selecting-descendant-elements-in-jquery – Björn Feb 20 '11 at 22:00
  • 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. – Zydeco Feb 20 '11 at 22:29