0

I have a small question regarding scoping when i use a custom callback function passed to jQuery.animate(). Consider the code below.

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

When i log the function context in the repositionPageNav callback i get a undefined, ideally i would have the context reference the element clicked on, as jQuery itself ussualy do. I could do this by changing the callback call to WebApi.scrollTo as follows:

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

By creating the closure the context inside the callback now refers to the element clicked as i intended but does this hurt performance? And 1 thing i cannot get my head around is why in the first example the context is undefined? Is it because i don't call the callback as callback.call(context)? Any suggestions/ideas?

Many Thanks,

Nick.

1 Answer 1

1

The this keyword acts more like a context, it is not the [variable] scope.

However, the problem seems more that you are instantly calling the repositionPageNav function (in both versions), instead of passing a callback function. If you would do so, the this will reference the DOM element the animation was called on.

Sign up to request clarification or add additional context in comments.

4 Comments

Ah context. I'll make sure to remember that. In the above examples doesn't the passed callback wait with execution until the animate() is finished?
As said, you do not pass any callback. You call the function immediately and pass the result (undefined).
So by passing it in as repositionPageNav($pageNav, $(this)) it calls it immediately? Perhaps passing jQuery.proxy(repositionPageNav, context, arguments) would be better suitable.
Yes, proxy (or native bind) would.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.