0

jQuery.animate() に渡されたカスタム コールバック関数を使用するときのスコーピングに関して、ちょっとした質問があります。以下のコードを検討してください。

;var WebApi = (function projectInit (WebApi, $, Modernizr, window, document, undefined) {

    $(element).on('click.skiptodocumentpart', function skipToDocumentPart (e) {
        WebApi.scrollTo(
            $(this.getAttribute('href')).offset().top, 
            1000, 
                $pageNav.length ? repositionPageNav($pageNav, $(this)) : null
        );
        return false;
    });

    function repositionPageNav ($pageNav, $elm) {
        console.log(this); // undefined
    };

    WebApi.scrollTo = function (yPos, iSpeed, callback) {
        $('html,body').animate({ 
            scrollTop : yPos 
        },{ 
            duration : typeof iSpeed === 'number' ? iSpeed : 1000, 
            complete : typeof callback === 'function' ? callback : null
    });
};

return WebApi;

}(WebApi || {}, jQuery, Modernizr, this, this.document));

repositionPageNav コールバックで関数コンテキストをログに記録すると、未定義になります。理想的には、jQuery 自体が通常行うように、コンテキストがクリックされた要素を参照するようにします。コールバック呼び出しを WebApi.scrollTo に次のように変更することで、これを行うことができます。

WebApi.scrollTo(
        yPos, 
        1000, 
        as$pageNav.length ? (function (scope) {
                return repositionPageNav.call(scope, $pageNav);
            }(this)) : null
        );

クロージャーを作成することにより、コールバック内のコンテキストは、意図したとおりにクリックされた要素を参照するようになりましたが、パフォーマンスが低下しますか? そして、私が理解できないことの1つは、最初の例でコンテキストが定義されていないのはなぜですか? コールバックを callback.call(context) として呼び出さないからですか? 提案/アイデアはありますか?

どうもありがとう、

ニック。

4

1 に答える 1

1

thisキーワードはcontextのように機能し、[variable] scopeではありません

ただし、問題はrepositionPageNav、コールバック関数を渡すのではなく、(両方のバージョンで) 関数を即座に呼び出すことです。その場合、はアニメーションが呼び出された DOM 要素this を参照します。

于 2013-02-19T16:59:11.957 に答える