如何让 JQuery 在旋转动画的循环内等待

Posted

技术标签:

【中文标题】如何让 JQuery 在旋转动画的循环内等待【英文标题】:How to make JQuery wait inside a loop in rotation animation 【发布时间】:2014-02-07 18:10:07 【问题描述】:

我有一个圆圈,里面有一个百分比文本,从 0% 开始。一旦我将圆圈悬停,它就会从 0 变为 100%(在圆圈周围有另一个效果)。就目前而言,百分比直接从 0 变为 100,我希望它显示进度(0,1,2...,99,100),但我无法让 JQuery 在每次 for 迭代之间等待。

这是我尝试过的:JSFiddle demo

注意:我的代码目前适用于 chrome。

这是一次迭代:

function actions(i)
    var box = $('#box');
    box.css('transform','rotate(' + i + ' deg)');
    box.css('-ms-transform','rotate(' + i + 'deg)');
    box.css('-webkit-transform','rotate(' + i + 'deg)');
    prec = (100*(i + 135))/360;
    $("div.prec").delay(100).html(Math.round(prec)+"%");

我知道delay() 需要排队,而html() 没有排队,所以我已经尝试过setTimeout,但它也不起作用。我也试过setInterval - 见下一个代码sn-p:

setInterval(function () 
    $("div.prec").html(Math.round(prec)+"%");
,100);

为了更清楚,我希望百分比适合效果进度 - 如果环绕的三角形行进一半,百分比应该是 50,因此,当我不再悬停圆圈时,它应该逐渐回到0。

【问题讨论】:

【参考方案1】:

首先,删除多余的transition: all 1s css 规则!这给所有解决方案都带来了麻烦。

1。教育 - 使用 setTimeout

for 循环不会像您期望的那样工作,javascript 不是为主动等待循环构建的,如下所示:

for (var i = -135; i < 225; i++)
    actions(i);
    sleep(some time);      

您必须使用超时和回调。禁用.delay 函数调用并将for 循环重写为迭代的setTimeout 回调,如下所示:

function loopit(dir, i)
    if (typeof i == "undefined") 
        i = -135;
    if (i >= 225)
        return;
    actions(i);
    setTimeout(function () 
        loopit(dir, i + 1);
    , 1);

反向旋转将被类推 - 你可以自己写它作为家庭作业:-)

http://jsfiddle.net/NNq3z/10/

2。简单 - 使用 jQuery .animate()

最简单的方法是使用jQuery .animate() 函数,它会为你做动画“循环”和计时。要为百分比文本设置动画,请使用 progress 回调。动画旋转很棘手,你需要使用special trick:

$( deg: deg_from  ).animate(
    deg: deg_to
, 
    duration: 1000,
    progress: function (animation, progress) 
        $("div.prec").html(Math.round(progress*100)+"%");
    ,
    step: function(now) 
        $('#box').css(
            transform: 'rotate(' + now + 'deg)'
        );
    
);

http://jsfiddle.net/q9VXC/1/

【讨论】:

你是对的,javascript不会逐行执行。而你的代码仍然有问题 谢谢,但这对我没有用。我更新了问题,以便更清楚地了解我想要实现的目标。 @ItayGal 问题是由transition: all 1s css 规则引起的。我删除了它,现在效果很好。我更新了我的解决方案,并使用 jquery .animate() 添加了更简单的解决方案。 是的,以前的情况下,当我悬停时,它开始将数字增加到 100,然后只有箭头移动。现在你绝对是完美的 @Kirk 是的 - 通过删除被诅咒的 transition: all 1s css 规则已修复。我根本没想到它会被css破坏:)【参考方案2】:

http://jsfiddle.net/NNq3z/13/

var i = -135,box = $("#box"),prec;
setTimeout(function()
if($("#circle").is(":hover"))
   loopit("c");
else
    loopit("nc");
,1);
function loopit(dir)
if (dir=="c")
    i++;        
else
    i--;
if(i<-135)
    i=-135;
if(i>225)
    i=225;
prec = (100*(i + 135))/360;   
$(".prec").html(Math.round(prec)+"%");
box.css("transform","rotate("+i+"deg)")
.css("-ms-transform","rotate("+i+"deg)")
.css("-moz-transform","rotate("+i+"deg)")
.css("-webkit-transform","rotate("+i+"deg)");
setTimeout(function()
if($("#circle").is(":hover"))
   loopit("c");
else
    loopit("nc");
,1);

删除了transition:all 1s。 在您的代码中,框的百分比立即变为 100%,因为您使用了 for 循环。 for循环会执行得非常快,好像马上就变100%一样,所以不推荐。

【讨论】:

按方向引用其他答案通常不是一个好主意。根据投票和接受的答案,顺序可能会改变。如果您需要参考特定答案,最好将链接放置到答案中。此外,“上面的代码仍然有一些错误”并没有真正解释太多。如果您提供一些解释,特别是您修复了哪些错误以及原因,这将是一个更好的答案。 你能补充解释吗。目前,您的解决方案更好,但缺乏适当的解释。虽然我理解,但这不是一个“好的”*** 答案。 这是一个抄袭 - 你从我的回答中拿走了我的小提琴,只是用微不足道的改变稍微更新了它! @ItayGal,你为什么接受这个? 实际上并没有那么相似,它可以工作,而您建议的解决方案却不能。您的答案包含更好的解释(为您投票),但您提供的示例有错误 - 例如,如果我将圆圈悬停,然后在它达到 100% 之前不悬停,动画会从 100% 开始倒计时,而不是到目前为止的百分比。另请参阅:meta.stackexchange.com/questions/216655/…【参考方案3】:

您应该使用setInterval,并且每次都必须增加percentage

var percentage = 0;
var timer = setInterval(function() 
    percentage++;
    if (percentage > 100) 
        clearInterval(timer);
     else 
        $("div.prec").html(percentage + "%");
    

您也可以在里面拨打actions()

【讨论】:

以上是关于如何让 JQuery 在旋转动画的循环内等待的主要内容,如果未能解决你的问题,请参考以下文章

vue进入页面两秒后转盘转动

opengl如何把glutIdleFunc的帧数调低,感觉转动时速度太快,可以不调角度来让旋转变慢么?

西克编码器拆卸方法

cocos creator 中怎么让一个节点在一块区域循环转动

如何让这个 jQuery 动画代码永远循环?

jQuery while循环不等待动画