2

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

一个->

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();
        }
    };

})();

乙->

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();
        }
    };

})();

编辑:请忽略容器部分,它与问题无关,它只是我没有取出的完整代码的一部分

4

3 回答 3

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,_用于私有变量。

于 2012-10-16T19:37:26.377 回答
1

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

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

于 2012-10-16T19:37:38.113 回答
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因为无论之前的回调是否完成,它都会在每个设置的时间间隔发出回调。

于 2012-10-16T19:33:46.377 回答