I'm sorry, I should have spotted the major bug in the code that I posted.

In fact, it's particularly embarrassing, because I wrote a recipe for the
jQuery Cookbook [1] on this exact topic. It's recipe 5.2, "What's Wrong with
$(this)?"

Inside the setTimeout callback function, "this" does not have the same value
that it has outside the function.

To fix it, copy your "this" value into another variable before calling
setTimeout:

var element = this;
setTimeout( function() {
    $(['li.',o.hoverClass].join(''),element)
        .add(element)
        .not(not)
        .removeClass(o.hoverClass)
        .find('>ul')
        .css('visibility','hidden');
}, 1000 );

Because 'element' is an ordinary JavaScript variable, it is available to the
inner nested function (the setTimeout callback).

BTW, here's a suggestion for another way to code the jQuery chain. It's six
of one, half a dozen of the other, but to my eyes this is a tiny bit easier
to follow:

var element = this;
setTimeout( function() {
    $(element)
        .find( 'li.' + o.hoverClass )
         .andSelf()
        .not(not)
        .removeClass(o.hoverClass)
        .find('>ul')
        .css('visibility','hidden');
}, 1000 );


-Mike

[1]: http://www.amazon.com/dp/0596159773/

On Thu, Dec 17, 2009 at 1:02 PM, decola <decola...@googlemail.com> wrote:

> thx for the quick answer, but this way i´ve tried it too. I have
> copied your code and test it too but it just don´t work.
>
> The function is called an a alert for example makes it output but the
> important code is not running like this.
>
> On 17 Dez., 18:21, Michael Geary <m...@mg.to> wrote:
> > You are calling the lengthy jQuery chain *first* and then passing its
> result
> > to setTimeout. Your code is equivalent to:
> >
> > var temp =
> >     $(['li.',o.hoverClass].join(''),this)
> >         .add(this)
> >         .not(not)
> >         .removeClass(o.hoverClass)
> >         .find('>ul')
> >         .css('visibility','hidden');
> >
> > setTimeout( temp, 1000 );
> >
> > Instead, you need to pass a *function* to setTimeout:
> >
> > setTimeout( function() {
> >     $(['li.',o.hoverClass].join(''),this)
> >         .add(this)
> >         .not(not)
> >         .removeClass(o.hoverClass)
> >         .find('>ul')
> >         .css('visibility','hidden');
> >
> > }, 1000 );
> >
> > -Mike
> >
> > On Thu, Dec 17, 2009 at 6:47 AM, decola <decola...@googlemail.com>
> wrote:
> > > setTimeout($(['li.',o.hoverClass].join(''),this).add(this).not
> > > (not).removeClass(o.hoverClass).find('>ul').css
> > > ('visibility','hidden'), 1000);
>

Reply via email to