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) として呼び出さないからですか? 提案/アイデアはありますか?
どうもありがとう、
ニック。