我知道我的问题,只是不知道如何解决。我有一个自定义域,在函数调用中执行while循环。在那个循环中,我希望动画按顺序出现。
因此,第一个问题是javascript本质上执行每一行,因此第2项在第1项完成之前开始。现在效果是如此之短,以至于它"似乎"同时发生在所有元素上,但在调试器中,它只是一次循环一个。
现在,我的典型解决方案是使用SetTimeout(),但这会导致浏览器锁定。阅读这篇文章(试图在jQuery中延迟/暂停/减慢while循环),浏览器进入无休止的循环是有道理的。
那么,如何在element1和element2事件之间获得暂停呢?我想也许可以在我的自定义域中添加一个回调函数,但除了不确定如何做到之外,我不确定这是否会如预期的那样工作
在页面的顶部阅读评论,了解我可能做错了什么或可以做得更好。
$(document).ready(function ()
{
//pause long enough for person to visually take in page before starting
setTimeout(function () { PageLoadAnimation.onReady(); }, 1000);
});
我的自定义域:
var PageLoadAnimation =
{
onReady: function ()
{
//black everything out just to be sure
PageLoadAnimation.BlackOutElements();
//flash & show
PageLoadAnimation.FlashElement();
},
BlackOutElements: function ()
{
$('#ParentContainer').children().hide();
},
FlashElement: function ()
{
//get array of all elements and loop till all are visible
var elementArray = $('#ParentContainer').children();
var $els = $('#PartialsContainer').children();
while (elementArray.length)
{
var $el = elementArray.eq(Math.floor(Math.random() * elementArray.length));
//if I put set timeout here is causes the infinite loop
PageLoadAnimation.FlashBlast($el);
elementArray = elementArray.not($el);
//if I put by itself it no diff as the while loop continues regardless
//setTimeout(1500);
}
},
FlashBlast: function ($el)
{
//flash background
$el.fadeIn(200, function () { $el.fadeOut(200) });
}
}
我不确定它是不起作用,还是我做错了什么,所以我创建了这些小提琴:
原始Fiddle
与Johan Callbacks
使用是设置属性的动画警告这个会挂起你的浏览器!我不认为我在像Johan想的那样检查isAnimating属性??
回答这种情况。希望它能帮助其他人
循环中的setTimeout确实是我的问题。。。但不是唯一的问题。我是另一个问题。
我先。
我真是个傻瓜,我做错了两件事,这真的让我自己陷入了困境。
首先使用jsfiddle,我的javascript会因为语法或诸如此类的事情而出错,但fiddle没有告诉你(据我所知),所以我的fiddle不会运行,但我很自豪,因为我的代码很好,愚蠢的javascript不起作用。
第二,我错误地将函数传递给了setTimeout。我添加了函数parens(),这也不正确,这会让我回到上面的问题。
WRONG: intervalTimer = setInterval(MyFunction(), 1500);
RIGHT: intervalTimer = setInterval(MyFunction, 1500);
至于我在这里读到的代码(http://javascript.info/tutorial/settimeout-setinterval)在循环中设置超时是不好的。循环将快速迭代,超时是循环中的一个步骤,我们将进入循环射击队。
这是我的实现:
我创建了几个变量,但不希望它们污染全局范围,所以我在自定义域中创建了它们。一个用于保存元素数组,另一个用于setInterval对象的句柄。
var PageLoadAnimation =
{
elementArray: null,
intervalTimer: null,
....
}
在我的onReady函数(页面调用它来启动)中,我设置了域数组变量,并设置了保存句柄的间隔,以备以后使用。请注意,间隔计时器是图像闪烁之间的间隔时间。
onReady: function ()
{
elementArray = $('#PartialsContainer').children();
//black everything out just to be sure
PageLoadAnimation.BlackOutElements();
//flash & show
intervalTimer = setInterval(PageLoadAnimation.FlashElement, 1500);
},
现在,我不是在数组中循环,而是以特定的间隔执行一个函数,并跟踪数组中还有多少元素需要闪烁。一旦数组中有零个元素,我就会终止间隔执行。
FlashElement: function ()
{
if(elementArray.length > 0) //check how many elements left to be flashed
{
var $el = PageLoadAnimation.GrabElement(); //get random element
PageLoadAnimation.FlashBlast($el); //flash it
PageLoadAnimation.RemoveElement($el); //remove that element
}
else
{
//done clear timer
clearInterval(intervalTimer);
intervalTimer = null;
}
},
所以整件事就是:
var PageLoadAnimation =
{
elementArray: null,
intervalTimer: null,
onReady: function () {
elementArray = $('#PartialsContainer').children();
//black everything out just to be sure
PageLoadAnimation.BlackOutElements();
//flash & show
intervalTimer = setInterval(PageLoadAnimation.FlashElement, 1500);
//NOT this PageLoadAnimation.FlashElement()
},
BlackOutElements: function () {
$('#PartialsContainer').children().hide();
},
FlashElement: function ()
{
if(elementArray.length > 0)
{
var $el = PageLoadAnimation.GrabElement();
PageLoadAnimation.FlashBlast($el);
PageLoadAnimation.RemoveElement($el);
}
else
{
//done clear timer
clearInterval(intervalTimer);
intervalTimer = null;
}
},
GrabElement: function()
{
return elementArray.eq(Math.floor(Math.random() * elementArray.length));
},
RemoveElement: function($el)
{ elementArray = elementArray.not($el); },
FlashBlast: function ($el) {
//flash background
$el.fadeIn(100, function () { $el.fadeOut(100) });
}
}
希望能帮助其他人理解如何在javascript中暂停执行。
一个可能有帮助的回调示例:
FlashBlast: function ($el, fadeInComplete, fadeOutComplete)
{
if(arguments.length === 3){
$el.fadeIn(200, function () {
fadeInComplete();
$el.fadeOut(200, fadeOutComplete);
});
}
}
用法:
PageLoadAnimation.FlashBlast($el, function(){
//fadein complete
}, function(){
//fadeout complete
});
另一个可能有帮助的想法:
isAnimating: false,
FlashBlast: function ($el)
{
var dfd = $.Deferred(),
that = this;
that.isAnimating = true;
$el.fadeIn(200, function () {
$el.fadeOut(200, function(){
dfd.resolve();
})
});
dfd.done(function(){
that.isAnimating = false;
});
}
然后利用私有财产CCD_ 1。
最后,要知道元素是否在动画下,可以使用$el.is(':animated')
。
希望这能有所帮助。如果有什么不清楚的地方,请告诉我。