1

I´m trying to create a JS/Jquery function to handle several image sliders on the same page.

Here´s my code:

var imageSlider = $('.imageSlider');

imageSlider.each(function(){
    var imageBackground = $(this).find('.imageBackground');
    var imageBackgroundFirst = $(this).find('.imageBackground:first');
    var imageBackgroundLast = $(this).find('.imageBackground:last');

    imageBackground.addClass('off');
    imageBackgroundFirst.removeClass('off').addClass('on');

    setInterval(function(){
        var imageBackgroundOn = $(this).find('.imageBackground.on');

        if (imageBackgroundLast.hasClass('on')){
            imageBackgroundLast.removeClass('on').addClass('off');
            imageBackgroundFirst.addClass('on').removeClass('off');
        }
        else{
            imageBackgroundOn.removeClass('on').addClass('off');
            imageBackgroundOn.next().addClass('on').removeClass('off');
        }

    }, 7500);
})

The problem is imageBackgroundOn variable inside set interval element returns undefined context... I know that setInterval handles variables in its own context, so how can I link the setInterval lines to work independent for every imageSlider element? I need that variable to be refreshed on every interval and in its own context.

Thanks in advance!

Niktus
  • 13
  • 2

2 Answers2

1

I would use Function.prototype.bind method:

setInterval(function(){
    var imageBackgroundOn = $(this).find('.imageBackground.on');

    if (imageBackgroundLast.hasClass('on')){
        imageBackgroundLast.removeClass('on').addClass('off');
        imageBackgroundFirst.addClass('on').removeClass('off');
    }
    else{
        imageBackgroundOn.removeClass('on').addClass('off');
        imageBackgroundOn.next().addClass('on').removeClass('off');
    }

}.bind(this), 7500);

IE8 doesn't support ES5 methods, so instead you can use $.proxy:

setInterval($.proxy(function() {
    // ...
}, this), 7500);

Or simply use reference to correct context:

var self = this;
setInterval(function() {
    var imageBackgroundOn = $(self).find('.imageBackground.on');
    // ...
}, 7500);
dfsq
  • 191,768
  • 25
  • 236
  • 258
1

I would recommend caching $(this) in a variable. This way you would also have the problem with undefined context for this in setInterval solved. Something like this:

var imageSlider = $('.imageSlider');

imageSlider.each(function(){
    var $this = $(this);
    var imageBackground = $this.find('.imageBackground');
    var imageBackgroundFirst = $this.find('.imageBackground:first');
    var imageBackgroundLast = $this.find('.imageBackground:last');

    imageBackground.addClass('off');
    imageBackgroundFirst.removeClass('off').addClass('on');

    setInterval(function(){
        var imageBackgroundOn = $this.find('.imageBackground.on');

        if (imageBackgroundLast.hasClass('on')){
            imageBackgroundLast.removeClass('on').addClass('off');
            imageBackgroundFirst.addClass('on').removeClass('off');
        }
        else{
            imageBackgroundOn.removeClass('on').addClass('off');
            imageBackgroundOn.next().addClass('on').removeClass('off');
        }

    }, 7500);
})
Pawel.W
  • 166
  • 1
  • 1
  • 8