在while循环锁定浏览器中暂停执行(用fiddles更新)

我知道我的问题我不知道如何解决它。 我有一个自定义域,并在函数调用中执行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) }); } } 

我不确定它是否不起作用或者我做错了所以我创建了这些小提琴:

原始小提琴

随着Johan Callbacks

使用是动画属性警告这一个将挂你的浏览器! 我不认为我按照约翰的方式检查isAnimating属性?


对此情况的回答。 希望它会帮助别人。

循环中的setTimeout确实是我的问题……但不是唯一的问题。 我是另一个问题。

我先。

我是傻瓜我真的因为我做错了两件事而引起了我自己的并发症。

首先使用jsfiddle我的javascript会因为语法或一些这样的事情而错误但是小提琴并没有告诉你(据我所知)所以我的小提琴不会运行但是我自豪地把它当作我的代码很精细愚蠢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; }); } 

然后利用私人财产isAnimating

最后,要知道元素是否在动画下,您可以使用$el.is(':animated')

希望这可以帮助。 如果有什么不清楚,请告诉我。