javascript时间事件问题(setTimeout / clearTimeout)

时间:2012-10-16 19:30:08

标签: javascript jquery timer settimeout

我一直很难处理时间事件。有人可以解释为什么A不起作用而B有效吗?唯一的区别在于A我将事件绑定放在一个函数中。不要担心功能关闭,它与问题无关。当我测试A时,没有js错误但是没有清除定时器。

A - >

Test.Navigation = (function() {

    var openTimer = null;
    var closeTimer = null;

    var addListeners = function() {
        $('.hover_container').on('mousemove', function(e) {

            clearTimeout(closeTimer);

        });

        $('.hover_container').on('mouseleave', function(e) {

            // set the close timer
            var container = this; 
            closeTimer = setTimeout(function() {
                //has the mouse paused
                close(container);
            }, 750);
        });

    };

    return {
        init : function() {
            addListeners();
        }
    };

})();

B - >

Test.Navigation = (function() {

    var openTimer = null;
    var closeTimer = null;

    $('.hover_container').on('mousemove', function(e) {

        clearTimeout(closeTimer);

    });

    $('.hover_container').on('mouseleave', function(e) {

        // set the close timer
        var container = this; 
        closeTimer = setTimeout(function() {
            //has the mouse paused
            close(container);
        }, 750);
    });


    var addListeners = function() {
        // nothing here
    };

    return {
        init : function() {
            addListeners();
        }
    };

})();

编辑:请忽略容器部分,它没有什么可以解决的问题它只是我没有拿出的完整代码的一部分

3 个答案:

答案 0 :(得分:1)

第一种方法使用this的范围是错误的。

尝试

var openTimer = null;
var closeTimer = null;
var self = this;

然后再

var container = self;

在您的代码中,例如A,

$('.hover_container').on('mouseleave', function(e) {
 // set the close timer
 var container = this;

this实际上是指当前的$('.hover_container')元素。

此外,由于setTimeout将在之前的setTimeout完成重新开始之前等待,因此您可能会出现差异。您可能希望切换到setInterval,因为无论先前的回调是否已完成,它都会在每个设置的间隔时间内发出回调。

答案 1 :(得分:1)

在对象存在于调用init之前绑定A。因为你返回一个新对象。如果您正在使用,则会创建2个对象。 1与vars en绑定。和1与回报。

B正在工作,因为您创建了一个初始化元素并使用正确范围的函数。 A无法正常工作,因为绑定的范围是错误的,因为您创建了2个对象:

new Test.Navigation(); // Create 1 object

// Create second object.
return {
    init : function() {
        addListeners();
    }
};

你最好得到这样的结构,然后它应该起作用:

Test.Navigation = (function() {
    // Private vars. Use underscore to make it easy for yourself so they are private.
    var _openTimer = null,
        _closeTimer = null;

    $('.hover_container').on('mousemove', function(e) {
        clearTimeout(_closeTimer );
    });

    $('.hover_container').on('mouseleave', function(e) {

        // set the close timer, 
        //    use $.proxy so you don't need to create a exta var for the container.
        _closeTimer = setTimeout(
                $.proxy(function() {
                    //has the mouse paused
                    close(this);
                }, this)
            , 750);

    });


    this.addListeners = function() {
        // nothing here
    };

    this.init = function() {
        this.addListeners();
    }

    // Always call the init?
    this.init();

    return this; // Return the new object Test.Navigation
})();

并像

一样使用它
var nav = new Test.Navigation();
nav.init();

另外,您可以看到我升级了您的代码。使用$.proxy_作为私人变种。

答案 2 :(得分:1)

我的猜测是,在调用代码中,您有一个语句new Test.Navigation(),对于B,在新的Test.Navigation()时调用addListeners。在A中,您返回一个调用init函数的对象引用。你能验证是否调用了init()吗?

即。在A中,必须在添加处理程序之前调用init()。在B中,每次实例化Test.Navigation时都会添加处理程序---如果你打算一次实例化多个Test.Navigation(),那么这取决于调用代码可能会很糟糕。