Jquery - 如何延迟后续动画?

时间:2016-08-21 03:28:23

标签: javascript jquery html css animation

好的,我有8个div,我需要让它们一次一个地进行动画,这意味着在第1和第2,第2和第3之间有延迟等。 起初我将它们全部设置为动画,然后根据一个dropdwin我将只动画几个或几个div。

无论我需要动画延迟再用另一个div运行。

这是我的动画:

function panelIn(labDiv)
        {

            var neww = "100%";
  $(labDiv).delay(600).animate({
    width: neww
  }, 500);

        }

起初我尝试设置一个全局变量并根据它来改变延迟,这对第1和第2个div有用,但不适用于所有后续:

function panelIn(labDiv)
        {
            if(wasFirst == true)
            {
                wasFirst = !wasFirst;
            var neww = "100%";
  $(labDiv).delay(600).animate({
    width: neww
  }, 500);
            }
            else {
                var neww = "100%";
  $(labDiv).delay(1200).animate({
    width: neww
  }, 500);
            }
        }

我必须做这样的事情:

panelIn(div1);
panelIn(div2);
panelIn(div3);
panelIn(div4);

希望避免在所有这些之间放置一些等待函数。这也很困难,因为我需要将第一个延迟600,第二个减少到12000,第三个到1800,依此类推。我需要它在panelIn func和1 set delay内。

如何让我的div一次一个地动画?可以这样做吗?

3 个答案:

答案 0 :(得分:2)

有8个div

<div class="animateContainer">
  <div class="animateThis">Item 1</div>
  <div class="animateThis">Item 2</div>
  <div class="animateThis">Item 3</div>
  <div class="animateThis">Item 4</div>
  <div class="animateThis">Item 5</div>
  <div class="animateThis">Item 6</div>
  <div class="animateThis">Item 7</div>
  <div class="animateThis">Item 8</div>
</div>

并且您希望能够触发它们中的每一个但是要延迟它们。第一个是延迟600,第二个是1200,第三个是1800,等等。

var elems = $(".animateThis");

function panelIn(divNumber){
 var neww = "100%";
 $(elems[divNumber]).delay(600 * (divNumber+1)).animate({
    width: neww
  }, 500);

}

panelIn(0);
panelIn(1);
panelIn(2);
panelIn(3);
panelIn(4);
panelIn(5);
panelIn(6);
panelIn(7);

您可以在https://jsfiddle.net/senordelaflor/h0z87r7f/2/

看到此解决方案

答案 1 :(得分:2)

尽管Pablo Martinez的答案向您展示了如何以编程方式修改延迟,但答案是有缺陷的:以这种方式执行意味着我们将每个动画超时(jQuery可能在内部或类似地使用setTimeout),并且到期对于JavaScript引擎的工作方式,动画可能会重叠,因为超时不是在指定的时间完全执行,只是大约。如果您尝试在每个动画的结尾或开始时触发事件,您可能会发现事件不会以预期的顺序触发(这是事实,但我不想举例证明它)。 / p>

为了保证连续触发动画 ,您应该使用.animate方法返回的promises按顺序运行动画,这样可以保证100%的动画会连续运行,从不重叠。

以下代码未经测试,其中的技术在this answer中进行了简要说明(注意,该答案也显示使用延迟的错误方式),并且实际上是相同的,但没有延迟时序近似:

const elems = $('.animateThis')

setTimeout(function() {
  panelIn(0)
  .then(() => panelIn(1)) // arrow function syntax
  .then(() => panelIn(2))
  .then(() => panelIn(3))
  .then(() => panelIn(4))
  .then(() => panelIn(5))
  .then(() => panelIn(6))
  .then(() => panelIn(7))
}, 500)

function panelIn(divNumber) {
  const neww = '100%'

  // return a promise (learn what promises are, they are useful!)
  return $(elems[divNumber]).delay(100).animate({
    width: neww
  }, 500).promise()
}

如果您处于支持异步功能的ES6 JavaScript环境中,则可以使代码更清晰:

async function sleep() {
  return new Promise(function(resolve) {
    return setTimeout(resolve, duration)
  })
}

function panelIn(divNumber) {
  const neww = '100%'

  return $(elems[divNumber]).delay(100).animate({
    width: neww
  }, 500).promise()
}

async function animateDivs() {
  const elems = $('.animateThis')

  // Fire each animation sequentially. The `await` keyword makes the engine wait for the given promise to be resolved.
  await sleep(500)
  await panelIn(0)
  await panelIn(1)
  await panelIn(2)
  await panelIn(3)
  await panelIn(4)
  await panelIn(5)
  await panelIn(6)
  await panelIn(7)
}

animateDivs()

使用sleep的箭头函数和for循环进一步缩短它:

const sleep = duration => new Promise(r => setTimeout(r, duration))

function panelIn(divNumber) {
  const neww = '100%'

  return $(elems[divNumber]).delay(100).animate({
    width: neww
  }, 500).promise()
}

async function animateDivs() {
  const elems = $('.animateThis')

  await sleep(500)
  for (let i=0; i<8; i++)
    await panelIn(i)
}

animateDivs()

奖励:如果您想在所有动画完成后做某事,只需编写另一个异步函数!

const sleep = duration => new Promise(r => setTimeout(r, duration))

function panelIn(divNumber) {
  const neww = '100%'

  return $(elems[divNumber]).delay(100).animate({
    width: neww
  }, 500).promise()
}

async function animateDivs() {
  const elems = $('.animateThis')

  await sleep(500)
  for (let i=0; i<8; i++)
    await panelIn(i)
}

async function animateDivsThenDoStuff() {
  await animateDivs()
  console.log('All animations complete!')
}

animateDivsThenDoStuff()

答案 2 :(得分:1)

来自我使用animationend的评论以及来自其他答案的HML和CSS代码

<强> CSS

.animate {
  width:100%;
    transition: width .5s linear;
}

<强>代码

var i = 1; 
    function animate() { 

    var thisone = $(".animate" + i);
    thisone.addClass('animate');

    thisone.on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',   
        function(e) {
        i++;
        if (i < 9) {
        animate();
        }
      });
    };

    animate();

Demo