KryptoniteDove
KryptoniteDove

Reputation: 1268

setTimeout time interval ignored in jQuery plugin

I've googled and come across a number of similar issues where people are trying to setTimeout in a jQuery plugin but to be i'm struggling with the answers, this is not a lazy post.

I am trying to achieve a delay in calling animate to hide some content, so for example if the user hovers over some area, some more content swings into view and hides the original. Then when the user moves the mouse away after 2 seconds the original content is returned.

The animation works as expected albeit ignoring the timeout. This is what I cannot get my head around!

Any assistance with the code would as always be greatly appreciated!

Here's the simplified code, focusing on the animation but I have left in place the plugin structure: -

;(function($){
$.fn.extend({         
    pluginName: function(options) {
        // - Settings list and the default values           
        var defaults = {
            width: this.css('width'),
        };

        var options = $.extend({}, defaults, options);   

        return this.each(function() {

        // --  Globals
            var o = options;    
            var timeoutID;

        function deceptionAnimate(display) {
            if(display == 1) {
                obj.clearQueue().animate({
                                        'top': 0,
                                        'left': -o.width 
                                        }, o.interval, o.easing);               
            } else if(display == 0) {
                obj.clearQueue().animate({
                                        'top': 0,
                                        'left': 0
                                        }, o.interval, o.easing)                
            } 
        }

        function delaydeceptionAnimate () {
            timeoutID = window.setTimeout(deceptionAnimate(0), 2000);
        }

        // ---- Initiate
        function init() {   
                        // ----- Animate

                        $(document).on(o.eventTrigger, wrapperID, function() {
                            deceptionAnimate(1);
                        });
                        $(document).on('mouseout', wrapperID, function() {
                            delaydeceptionAnimate(0);
                        });     
        }       
        // Call
        init();

        });
    }
});
})(jQuery);

Upvotes: 1

Views: 949

Answers (2)

CSilivestru
CSilivestru

Reputation: 76

You want to be careful about how you write the timeout function call. Here, you're actually calling delayedDeceptionAnimate rather than passing it as a function attribute to the setTimeout function.

Try rewriting that block as this:

function delaydeceptionAnimate () {
    timeoutID = window.setTimeout(function() {
        deceptionAnimate(0);
        }, 2000);
}

This way, you're passing a callback function that then calls the delayedDeceptionAnimate function!

Upvotes: 0

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324650

window.setTimeout(deceptionAnimate(0), 2000);

You are calling deceptionAnimate with parameter 0 and then passing its return value (null) to setTimeout as the function to be called.

In this particular case, you can rewrite deceptionAnimte like so:

function deceptionAnimate(display) {
    if( display) { /* code to show box */ }
    else { /* code to hide box */ }
}

Then use this:

window.setTimeout(deceptionAnimate, 2000);

But in the more general case, to pass an argument to the function to be delayed, use an anonymous function:

window.setTimeout(function() {deceptionAnimate(0);}, 2000);

Upvotes: 4

Related Questions