earthman
earthman

Reputation: 15

jQuery carousel "this" context not being passed into .animate callback

I am rolling my own carousel code, (modeled after the great write-up located here http://www.queness.com/post/923/create-a-simple-infinite-carousel-with-jquery) but I am encountering an issue when passing in the "this" selector context, but only within slider.animate(). The initial .before() works with the $("ul.slides li:first", this) and $("ul.slides li:last", this) selectors, since it is outside of a .animate().

I have a jQuery plugin declared as such:

$.fn.promoSlider = function(opts) {
    $(this).data('initialized', true);

    var speed = 400;
    var item_width = 274.5;
    var left_value = item_width * (-1);

    var slider =  $("ul.slides", this);

    //'this' works
    $("ul.slides li:first", this).before($("ul.slides li:last", this));
    slider.css({'left' : left_value});

    $('.btnprev', this).click(function() {
        var left_indent = parseInt(slider.css('left')) + item_width;

        slider.animate({'left' : left_indent}, speed, function() {
            //'this' does not work
            $("ul.slides li:first", this).before($("ul.slides li:last", this));
            slider.css({'left' : left_value});
        });
        return false;
    });

    $('.btnnext', this).click(function() {
        var left_indent = parseInt(slider.css('left')) - item_width;

        slider.animate({'left' : left_indent}, speed, function() {
            //'this' does not work
            $("ul.slides li:last", this).after($("ul.slides li:first", this));
            slider.css({'left' : left_value});
        });
        return false;
    });
}

Then I am initializing my carousels and passing in 'this' to the plugin like so:

        $('.carousel').each(function() {
            if($(this).data('initialized') !== true) {
                $(this).promoSlider();
            }
        });

The selector context 'this' gets lost inside .animate(), and I am not allowed to pass 'this' into the anonymous callback function. Thus $("ul.slides li:first", this).before($("ul.slides li:last", this)); never gets resolved, but only within the .animate() events.

Any help would be greatly appreciated. Thank you in advance for taking a look at this.

Upvotes: 1

Views: 535

Answers (1)

PSL
PSL

Reputation: 123739

Try this way:

yes the this content inside animate will be of that of slider. SO you can set up the context to another variable and access it inside the callback.

 var $this = this; //Set up the context to a variable here
  slider.animate({'left' : left_indent}, speed, function() {
            $("ul.slides li:first", $this).before($("ul.slides li:last", $this)); // access it.
            slider.css({'left' : left_value});
        });

You can also use $.proxy to set the callback function to a specific context.

slider.animate({'left' : left_indent}, speed, $.proxy(function() { //Set up the proxy for callback
                $("ul.slides li:first", $this).before($("ul.slides li:last", $this)); // access it.
                slider.css({'left' : left_value});
            },this)); //Set the context. now withinthe animate callbnack this will refer to the context you pass here.

Upvotes: 0

Related Questions