I have written a few custom animation functions as jQuery plugins using a setInterval() for the loop.
The functions seem to work fine by themselves but when I try to include more than one of them in the same page the timings and effects get all messed up and don’t render or complete properly!
I have done some scouting around on stackOverflow and google and from what I can gather the problem is that setInterval acts as a ‘global’ method / property of the window object and so when I have more than one on the page they end up overwriting each other!
Is this correct? And if so what is the solution? What does jQuery / plugins do to manage their own unique interval functions?
I was wondering if it’s possible to set a ‘local’ setInterval as a unique property to each of my plugin objects?
— OR —
If I have to create a function to manage multiple animation calls from various different plugins / functions to juggle them all with one global setInterval call — But I have no idea how to do this!
Can anyone help please?
—-edit—-
(function($){
$.fn.scroller = function(options) {
var defaults = {
direction: 'left',
distance: '',
duration: 2000,
interval: 2000,
type: 'linear',
startPos: '0'
};
var options = $.extend(defaults, options);
return this.each(function() {
parent = $(this).children('.scroller');
$this = parent.children().first();
// console.log(parent);
// console.log($this);
var o = options;
var m = '';
if(o.direction === 'left') m = 'marginLeft';
if(o.direction === 'right') m = 'marginRight';
if(o.direction === 'up') m = 'marginTop';
if(o.direction === 'down') m = 'marginBottom';
// console.log('Distance: ' + o.distance);
// console.log('Duration: ' + o.duration);
// console.log('Type: ' + o.type);
// console.log('Start Pos: ' + o.startPos);
// console.log('Interval: ' + o.interval);
setInterval(function(){
$this.animate({
m : o.distance
},
o.duration,
o.type,
function() { // OnComplete
$this.stop().css(m, o.startPos).appendTo(parent);
});
}, o.duration+o.interval);
});
};
})(jQuery);
Update
I think I see the problem. You define $this as a global variable. As such, calls to setInterval will all use the same $this variable. Try
var $this = .... Same forparent. Also note that in the callback to$this.animate, “this” should refer to the dom element that was animated, so you could do $(this) to get a jQuery object for it.I think your problem might be that you loose context with setInterval. The
thisobject may not be what you expect it to be. If you expect a variable to be present (because it was defined near where you call setInterval), it probably won’t be.Closures might help you. Try
Rather than
Also, try to make sure you are using locally defined variables in your setInterval callback rather than global ones:
rather than
If you used the second method, you would end up sharing the variable between callbacks.