Search code examples
javascriptjquerysettimeoutdhtml

Jquery effects with setTimeout


OK, I am missing something fundamental here I am sure! But for the life of me can not work it out.

Scenario

It's a simple hide show menu;

// Setup hover
        var fadeDuration = 200;
        var setDelay;
        $level1Item.hover(function () {
            $(this).addClass('hover').find('.level-2').fadeIn(fadeDuration);
        }, function () {
            $(this).removeClass('hover').find('.level-2').fadeOut(fadeDuration);
        });

And it works fine... but the drop down is rather LARGE and is irritating when it pops up all be it very sexily when you mouse moves from top to bottom of screen.

So I want to set a timeout and clear it on mouse out...

// Setup hover
        var fadeDuration = 200;
        var setDelay;
        $level1Item.hover(function () {
            setDelay = setTimeout("$(this).addClass('hover').find('.level-2').fadeIn(200)", 500);
            //$(this).addClass('hover').find('.level-2').fadeIn(fadeDuration);
        }, function () {
            clearTimeout(setDelay);
            $(this).removeClass('hover').find('.level-2').fadeOut(fadeDuration);
        });

ABSOLUTELY NOTHING HAPPENS!! I have tried alerts in the timeout function and they work... originally the variable fadeDuration was undefined but a number stops the console error.


Solution

  • You can't use this in the setTimeout-code, since this depends on the context. So when the timeout fires, the this is a different this... bad English, but hopefully it makes sense.

    Also, avoid using strings in timers; use functions instead. While you can use a string, which is then evaluated as JavaScript, it's generally bad form compared to simply wrapping the same code in a function

    var fadeDuration = 200;
    var setDelay;
    $level1Item.hover(function () {
        var element = $(this);
        setDelay = setTimeout(function() {
            element.addClass('hover').find('.level-2').fadeIn(fadeDuration);
        }, 500);
    }, function () {
        clearTimeout(setDelay);
        $(this).removeClass('hover').find('.level-2').fadeOut(fadeDuration);
    });