javascript - 避免 JS 中的顺序动画回调地狱
问题描述
我有一个网络项目,我想为五个彩色 div 的不透明度设置动画,使它们依次“闪烁”,然后用户以相同的顺序单击它们(就像 Simon 说的那样)。演示序列在用户单击按钮时开始,并且按钮也会淡出,因此只能单击一次。我的代码是这样的(仅用于演示动画,目前不关心用户响应):
function circleBlink(elem, callback) {
elem.animate({'opacity':'0'}, function() {
elem.animate({'opacity':'1'}, function() {
if (callback && typeof callback === 'function') {
callback();
}
});
});
}
function runThrough() {
circleBlink($('.sequence-options > .red-orange'), function() {
circleBlink($('.sequence-options > .blue'), function() {
circleBlink($('.sequence-options > .yellow'), function() {
circleBlink($('.sequence-options > .green'), function() {
circleBlink($('.sequence-options > .purple'));
});
});
});
});
}
$('.start-btn').click(function() {
$that = $(this);
$that.animate({'opacity': '0'}, function() {
$that.addClass('hidden');
});
runThrough();
setTimeout(runThrough, 5000);
});
该代码按原样工作正常,但我想知道是否有一种不那么冗长/性能更高/最佳实践的方式来重构它。我正在使用 jQuery,但不想为这个特定项目引入任何其他动画库或插件
解决方案
你可以为它创建一个animate
返回 Promise 的包装函数,也可以circleBlink
变成一个返回 Promise 的函数。您还可以使用箭头函数来避免丑陋that = this
:
const animateWithOpacity = (jqElm, opacity) => new Promise(resolve => {
jqElm.animate({ opacity }, resolve);
});
async function circleBlink(elem) {
await animateWithOpacity(elem, '0');
await animateWithOpacity(elem, '1');
// async function will automatically return promise that resolves when end is reached
}
async function runThrough() {
const classes = ['red-orange', 'blue', 'yellow', 'green', 'purple'];
for (const className of classes) {
await circleBlink($('.sequence-options > .' + className));
}
}
$('.start-btn').click(function() {
animateWithOpacity($(this), 0)
.then(() => $(this).addClass('hidden'));
runThrough();
setTimeout(runThrough, 5000);
// might also be able to `runThrough().then(runThrough)` if the timing is right
});
推荐阅读
- go - 如何通过 ssmtp 在 golang 中发送邮件
- go - How do I refactor module name in Go?
- flutter - 如何在应用程序中心创建具有左/右边距的列?
- c# - 在 Unity 中制作游戏时,我遇到了 C# 中的 OnCollisionEnter 函数的问题
- java - Unchecked cast from generic type to the same type
- angular - Pass dynamic data from parent to child component in Angular 7
- asynchronous - What happens if two dart asynchronous functions try to add to the same List concurrently?
- react-native - React-Native:动画视图阻止了 TouchableOpacity 的 onPress 动作
- ajax - Ajax onevent 未在 IE11 上触发
- google-calendar-api - 谷歌日历活动发布链接在 PC 上工作,在移动设备上不能正常工作