2

私はいつもタイムイベントを扱うのに苦労していました。Aが機能せず、Bが機能する理由を誰かに説明してもらえますか?唯一の違いは、AIがイベントバインディングを関数に配置することです。関数closeについて心配する必要はありません。質問とは何の関係もありません。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();
        }
    };

})();

編集:コンテナの部分は無視してください。それは、私が取り出さなかった完全なコードの一部にすぎないという質問には何の意味もありません。

4

3 に答える 3

1

Aは、initが呼び出されるオブジェクトが存在する前にバインドされます。新しいオブジェクトを返すからです。を使用している場合は、2つのオブジェクトが作成されます。1とvarsenがバインドします。と1リターンで。

要素が初期化され、適切なスコープを使用する関数を作成するため、Bが機能しています。2つのオブジェクトを作成したため、バインディングが間違ったスコープにあるため、Aは機能していません。

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の場合、新しいTest.Navigation()時にaddListenersが呼び出されるステートメントがあります。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 に答える