大家好,提前感谢您的宝贵时间!
我正在处理一个涉及同步 CSS3 动画的网站。我正在使用 setInterval() 调用来运行动画。我正在寻找在动画结束后调用函数的最佳方式。
下面的代码只是解释我的问题的通用示例。当您按下开始按钮时,将调用三个 setInterval() 函数。一个是平移动画,一个是缩放动画,最后一个是旋转动画。我的问题的本质是,我怎样才能运行一些代码——为了争论,我们说 console.log("We Did IT!"); - 当调用最后一个 clearInterval() 时。
我可以想象一个 bool 网络跟踪哪些动画已经完成并在抛出所有标志时调用代码,但我希望在这里可以找到更优雅的解决方案。
再次感谢!
//Global Variable Declarations
var adc = adc || {};
adc.tWrap = document.createElement('div');
adc.sWrap = document.createElement('div');
adc.rWrap = document.createElement('div');
adc.btn = document.createElement('button');
//Style Objects, Append to Body, Apply Listeners
adc.init = function() {
adc.setDiv(adc.tWrap, "transform wrap", 22, 22, 200, 200, 1, "");
adc.setDiv(adc.sWrap, "scale wrap", 22, 22, 150, 150, 2, "", "");
adc.setDiv(adc.rWrap, "rotate wrap", 22, 22, 100, 100, 3, "yellow");
adc.setBtn(adc.btn, "start btn", 25, 25, 50, 50, "Start");
var body = document.getElementsByTagName('body');
body[0].appendChild(adc.tWrap);
adc.tWrap.appendChild(adc.sWrap);
adc.sWrap.appendChild(adc.rWrap);
adc.rWrap.appendChild(adc.btn);
adc.btn.addEventListener('click', adc.click, true);
}
adc.setDiv = function(a, id, T, L, H, W, z, bg) {
a.id = id;
a.style.position = 'absolute';
a.style.top = T + "px";
a.style.left = L + "px";
a.style.height = H + "px";
a.style.width = W + "px";
a.style.zIndex = z;
a.style.borderWidth = "3px";
a.style.borderStyle = "solid";
a.style.backgroundColor = bg;
}
adc.setBtn = function(a, id, T, L, H, W, txt) {
a.id = id;
a.type = "button";
a.textContent = txt;
a.style.position = 'absolute';
a.style.top = T + "px";
a.style.left = L + "px";
a.style.height = H + "px";
a.style.width = W + "px";
}
//Event Listener
adc.click = function() {
if (!adc.animate.runLock()) {
adc.animate.trans.start();
adc.animate.scale.start();
adc.animate.rotate.start();
}
}
//Animation Routines (setInterval calls)
adc.animate = {
runLock: function() {
if (adc.animate.trans.run == 0 && adc.animate.scale.run == 0 && adc.animate.rotate.run == 0) {
return false;
} else {
return true;
}
},
trans: {
run: 0,
count: 0,
flag: false,
start: function() {
this.run = setInterval(function() {
adc.animate.trans.EXE()
}, 10);
},
stop: function() {
clearInterval(this.run);
this.run = this.count = 0;
this.flag = false;
},
EXE: function() {
if (!this.flag) {
this.count += 0.5;
} else {
this.count -= 0.5;
}
if (this.count >= 45) {
this.flag = true;
}
adc.tWrap.style.transform = "translateX(" + this.count + "px)";
if (this.count <= 0) {
this.stop();
}
}
},
scale: {
run: 0,
count: 1,
flag: false,
start: function() {
this.run = setInterval(function() {
adc.animate.scale.EXE()
}, 10);
},
stop: function() {
clearInterval(this.run);
this.run = 0;
this.count = 1;
this.flag = false;
},
EXE: function() {
if (!this.flag) {
this.count += 0.01;
} else {
this.count -= 0.01;
}
if (this.count >= 1.9) {
this.flag = true;
}
adc.sWrap.style.transform = "scale(" + this.count + ")";
if (this.count <= 1) {
this.stop();
}
}
},
rotate: {
run: 0,
count: 0,
flag: false,
start: function() {
this.run = setInterval(function() {
adc.animate.rotate.EXE()
}, 10);
},
stop: function() {
clearInterval(this.run);
this.run = this.count = 0;
this.flag = false;
},
EXE: function() {
if (!this.flag) {
this.count++;
} else {
this.count--;
}
if (this.count >= 90) {
this.flag = true;
}
adc.rWrap.style.transform = "rotate(" + this.count + "deg)";
if (this.count <= 0) {
this.stop();
}
}
}
}
//Initialization Call
document.addEventListener('DOMContentLoaded', function() {
adc.init();
});
<!DOCTYPE html>
<html>
<head></head>
<body></body>
</html>
最佳答案
Lo-Dash 有一个方便的函数,叫做 _.after
在一定次数的调用后执行给定的函数。例如,以下函数仅在所有超时完成后执行。
var finish = _.after(5, function () {
console.log('All functions completed!');
});
setTimeout(function () { console.log('A'); finish(); }, 500);
setTimeout(function () { console.log('B'); finish(); }, 1000);
setTimeout(function () { console.log('C'); finish(); }, 1500);
setTimeout(function () { console.log('D'); finish(); }, 2000);
setTimeout(function () { console.log('E'); finish(); }, 2500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
如果你不想包含 Lo-Dash,你可以很容易地自己实现 _.after
:
function callAfter(n, func) {
var i = 0;
return function () {
if (i < n) { i++; }
else { return func(); }
};
}
关于javascript - 在多个 setInterval 函数完成时执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27585511/