重复一段时间后,间隔不会立即清除

时间:2016-01-25 22:23:33

标签: javascript jquery css

我的网站上有一个用Jquery和setInterval创建的弹跳箭头,如下所示:

bouncing = setInterval(function() {
    $("div").animate({
        top:"30px"
    },100,"easeInCubic",function() {
        $("div").animate({
            top:"0px"
        },100,"easeOutCubic");
    });
    console.log("bounced");
},200);

您可以在此处的codepen中看到这一点:http://codepen.io/mcheah/pen/wMmowr

我让它比我需要的更快,因为它更容易更快地看到问题。我的问题是,在间隔运行几秒钟之后,你会注意到,不是立即向上或向下弹跳,弹跳元件将停止半秒然后只是挂在那里,然后重新开始。如果你让它运行得更长(20秒)然后清除间隔,你会注意到它需要几秒钟才能停止弹跳。

我的问题是这些:

  1. 为什么弹跳偶尔会失去同步?

  2. 为什么清除间隔需要一段时间才能清除它是否已经重复了一段时间?

  3. 有没有更好的方法来获得弹跳箭头? CSS过渡更可靠吗?

  4. 感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

您正在尝试完美地协调setInterval()计时器和两个jQuery动画,以便两者完美协调。这是在寻找麻烦,两者可能会随着时间的推移而分开,所以它被认为是一种糟糕的设计模式。

相反,如果你只是使用第二个动画的完成来重新启动第一个并重复那样,那么每次都有完美的协调。

您可以在另一个版本的codepen中看到:http://codepen.io/anon/pen/NxYeyd

function run() {
    var self = $("div");
    if (self.data("stop")) return;
    self.animate({top:"30px"},100, "easeInCubic")
        .animate({top:"0px"}, 100, "easeOutCubic", run);
}

run();


$("div").click(function() {
    // toggle animation
    var self = $(this);
    // invert setting to start/stop
    self.data("stop", !self.data("stop"));
    run();
    console.log("toggled bouncing");
});

答案 1 :(得分:1)

  1. 以这种方式将animate()与计时器混合在一起并不是一个好主意。有 NO 的机会你可以同步这样的东西。而且没有必要。您只需将一个函数附加到动画队列中,请查看此处:https://stackoverflow.com/a/11764283/3227403

  2. animate()所做的是将动画请求放入作业队列,稍后将在合适的时间到来处理。当您中断间隔时,仍会处理队列中累积的内容。有一种清除队列并立即停止所有动画的方法。

  3. JQuery动画函数实际上是在操纵CSS,而HTML中除了它之外什么都没有。另一种选择是使用画布,但这是一种完全不同的方法,我不推荐它。使用JQuery的动画,您已经是最佳选择。

  4. 这是解决问题的简单方法:

    function bounce()
    {
      $("div")
        .animate({
          top: "30px"
        }, 100, "easeInCubic")
        .animate({
          top: "0px"
        }, 100, "easeOutCubic", bounce); // this loops the animation
    }
    

    开始在页面加载时弹跳:

    $(bounce);
    

    点击时停止弹跳:

    $("div").click(function() {
      $("div").stop().clearQueue().css({ top: "0px" });
      // you want to reset the style because it can stop midway
    });
    

    编辑:我现在纠正了一些不准确之处。正在运行的示例位于codepen now

答案 2 :(得分:0)

如果你想使用javascript动画,你可以使用更好的绿色补间库 http://greensock.com/docs/#/HTML5/GSAP/TweenMax/to/ 像这样的东西:

var tween = TweenMax.to($("div"), 100, {y: "100px", yoyo: true, repeat: -1});

答案 3 :(得分:0)

您可以使用以下内容包装区间代码:

if(!$("div").is(":animated"))

仅当您之前的动画完成时,才会启动动画。 它之所以出现奇怪的原因是你的动画排队了。 您现在可以查看它的工作原理: http://codepen.io/luminaxster/pen/XKzLBg

我建议在第二个动画结束时使用完整的回调,并使用变量来控制此版本中的反弹递归调用:

http://codepen.io/luminaxster/pen/qNVzLY