破旧的动画序列

时间:2013-12-13 00:38:40

标签: javascript jquery

这最初来自(Pause execution in while loop locks browser (updated with fiddles)

我整天都在这里,我无法弄清楚如何让javascript继续前进到下一行,并且本质上一次执行所有行。我已经尝试了延迟/ setTimeout的每一个组合,我能想到无济于事。

我只是希望数组中的元素闪烁一次然后暂停,然后再次为数组中的另一个元素执行此操作,直到所有元素都被删除并且数组为空。

但是因为javascript一次执行所有行我最终会同时闪烁所有元素的外观。

这是小提琴:

http://jsfiddle.net/ramjet/xgz52/7/

和相关代码:

FlashElement: function () {

  while (elementArray.length) {
    alert('a ' + elementArray.length);
    var $el = elementArray.eq(Math.floor(Math.random() * elementArray.length));

    PageLoadAnimation.FlashBlast($el);
    alert('delay complete');

    elementArray = elementArray.not($el);
    alert('array popped');

    alert('z ' + elementArray.length);
  }
},

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

正如Zach Saucier所指出的那样,循环确实是我的问题......但不是唯一的问题。我是另一个问题。

我先。

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

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

第二,我错误地将我的函数传递给setTimeout。我正在添加函数parens(),这也不正确,这会让我回到上面的问题。

WRONG: intervalTimer = setInterval(MyFunction(), 1500);

RIGHT: intervalTimer = setInterval(MyFunction, 1500);

至于代码。正如Zach指出的那样,我在这里阅读(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中暂停执行的方法。

1 个答案:

答案 0 :(得分:1)

您遇到问题的原因是因为setTimeout功能是非阻塞的并且会立即返回。因此,循环将非常快速地迭代,在彼此的毫秒内启动每个超时,而不是包括前一个延迟

因此,您需要创建一个自定义函数,在setInterval等待再次运行之前等待

FlashElement: function () { // Call it where you had the function originally
    myLoop();
},
...

function myLoop() {
   setTimeout(function () {    //  call a setTimeout when the loop is called
      var $el = elementArray.eq(Math.floor(Math.random() * elementArray.length));
      PageLoadAnimation.FlashBlast($el);
      elementArray = elementArray.not($el); 
      if (0 < elementArray.length) {  //  if the counter < length, call the loop function
         myLoop();
      }
   }, 1000)
}

jsFiddle

随意将延迟更改为您想要的任何值(3000ms,让每个淡入淡出在此刻之前完成)。如果您想在前一个结束之前开始淡入淡出,并将它们保持在原始位置,则必须使用.css设置不透明度的动画,而不是使用fadeInfadeOut < / p>

我的回答是基于另一个SO问题的this answer