1

Can't figure out why this thing happens.

var thumb_width = 240;
var thumb_height = 180;
$('.video-thumbnail').on({
        'mouseenter': function(){
            var i = 0; var j = 0;
            $(this).id = setInterval(function(){
                $(this).animate({
                    'background-position-x': -(j * thumb_width),
                    'background-position-y': -(i * thumb_height)
                });
                i++; j++;
            }, 1000);
        }
    })
});
Dmitrii Mikhailov
  • 5,053
  • 7
  • 43
  • 69
  • Side note: You can use [.mouseenter()](https://api.jquery.com/mouseenter/) instead of on.('mouseenter', function() {... – Tomanow Feb 16 '14 at 13:22

2 Answers2

1

Because setInterval runs in Window context. In order to fix it you should explicitly provide proper object context. You have couple of options:

Using $.proxy:

$('.video-thumbnail').on({
    'mouseenter': function() {
        var i = 0; var j = 0;
        $(this).id = setInterval($.proxy(function() {
            $(this).animate({
                'background-position-x': -(j * thumb_width),
                'background-position-y': -(i * thumb_height)
            });
            i++; j++;
        }, this), 1000);
    }
});

Or using reference to this:

$('.video-thumbnail').on({
    'mouseenter': function() {
        var i = 0; var j = 0, self = this;
        $(this).id = setInterval(function() {
            $(self).animate({
                'background-position-x': -(j * thumb_width),
                'background-position-y': -(i * thumb_height)
            });
            i++; j++;
        }, 1000);
    }
});
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • As third option you could use [.bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) – Krzysztof Romanowski Feb 17 '14 at 08:45
  • 1
    I thought about including this option in the list, but `$.proxy` is iteself `bind` cross-browser implementation. – dfsq Feb 17 '14 at 08:47
0

You are assuming a wrong context in the setInterval's callback, as setInterval is bound to the global object (window).

Also the background-position-x and background-position-y aren't part of any CSS specification and you cannot set them apart (read more in that answer).

Try this:

...
var $this = $(this);
$this.id = setInterval(function() {
  var xPos = -(j * thumb_width);
  var yPos = -(i * thumb_height);
  $this.animate('background-position', xPos + 'px ' + yPos + 'px');
  ++i;
  ++j;
}, 1000);
...
Community
  • 1
  • 1
Radko Dinev
  • 865
  • 7
  • 15