如何让多个 Javascript setInterval 函数在同一页面上很好地协同工作?
我使用 setInterval()
循环编写了一些自定义动画函数作为 jQuery 插件。
这些功能本身似乎运行良好,但是当我尝试在同一页面中包含多个功能时,时间和效果都会变得混乱,并且无法正确渲染或完成!
我在 stackOverflow 和 google 上进行了一些搜索,从我收集到的信息来看,问题是 setInterval
充当 window
对象的“全局”方法/属性,所以当我在页面上有多个时,它们最终会相互覆盖!
这是正确的吗?如果是这样,解决方案是什么? jQuery/插件如何管理自己独特的间隔函数?
我想知道是否可以将“本地”setInterval
设置为每个插件对象的唯一属性?
-- 或者 --
如果我必须创建一个函数来管理来自各种不同插件/函数的多个动画调用,以便通过一个全局 setInterval
调用来处理它们 -- 但我不知道如何做到这一点!
有人可以帮忙吗?
- - 编辑 - -
(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);
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);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更新
我想我看到了问题。您将 $this 定义为全局变量。因此,对 setInterval 的调用都将使用相同的 $this 变量。尝试
var $this = ...
。与父级
相同。另请注意,在$this.animate
的回调中,“this”应该引用动画的 dom 元素,因此您可以执行 $(this) 来获取它的 jQuery 对象。我认为你的问题可能是你失去了 setInterval 的上下文。
this
对象可能不是您期望的那样。如果您希望存在一个变量(因为它是在调用 setInterval 的位置附近定义的),那么它可能不会出现。关闭可能会帮助你。尝试
而不是
另外,尝试确保您在 setInterval 回调中使用本地定义的变量而不是全局变量:
而不是
如果您使用第二种方法,您最终将在回调之间共享变量。
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
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
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.
setInterval 确实是全局的,但每次调用 setInterval 都会返回一个唯一的 ID,您可以用它来引用它,即clearInterval()。每个需要自己的间隔的插件都应该分配自己的变量来包含引用的 ID。也许这取决于您如何单独管理其中的每一个。您有任何代码可以向我们展示吗?
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?