How can I get multiple Javascript setInterval functions to play nicely together on the same page?
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 for parent
. 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 this
object 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
setInterval(function(){
//code here
});
Rather than
setInterval(myPreDefinedFunction);
Also, try to make sure you are using locally defined variables in your setInterval callback rather than global ones:
var myVar = 5;
rather than
myVar = 5;
If you used the second method, you would end up sharing the variable between callbacks.
it is true that setInterval is global, but each call to setInterval returns a unique ID that you can use to reference it, i.e. for clearInterval(). Each plugin requiring it's own interval should be assigned it's own variable to contain the ID for referencing. Perhaps it's coming down to how you are managing each of these individually. Do you have any code to show us?
精彩评论