考虑这个函数
async function Animate(element)
{
// do something with dom element's animation, triggering it
element.addEventListener("animationend",
function(event)
{
// this is when Animate(element) should resolve/return
}
}
是否有任何方法来处理这种情况,并实际上有一个async函数解析/返回事件监听器回调?
使用承诺。在animationend事件监听器中解析它。
const animateThis = async(elem) => {
return new Promise(resolve => {
elem.classList.add("active");
elem.addEventListener('animationend', () => {
elem.classList.remove("active");
resolve();
});
});
};
(async function() {
const elem = document.querySelector(".animation");
console.log("before call");
await animateThis(elem);
console.log("after call");
}());
.animation.active {
animation-duration: 2s;
animation-name: slidein;
animation-iteration-count: 2;
}
@keyframes slidein {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 0%;
width: 100%;
}
}
<p class="animation">Hello World</p>
你可以在async函数中返回或等待一个新的Promise,并在事件处理程序中调用它的解析器,但是大多数事件(animationend是其中的一部分)可能永远不会触发,所以你可能在等待一些永远不会发生的事情。
在这个动画结束的特殊情况下,你可以解决这个问题,这要感谢Web-Animations API,它暴露了一个finished
承诺,如果动画在预期结束之前停止,它将解决或拒绝:
const elem = document.querySelector(".animate");
(async () => {
// never gonna resolve
const prom = new Promise((resolve) => {
elem.addEventListener("animationend", () => resolve(), { once: true });
});
// await prom;
prom.then(()=>console.log("event fired"));
// using the Web Animation API
// we should do more filtering on the Animations here
// to be sure we get our own
const anim = elem.getAnimations()[0];
try {
await anim.finished;
}
catch(err) { }
console.log("anim ended");
})().catch(console.error);
// stop the animation before completion
setTimeout(() => elem.remove(), 2000);
.animate {
width: 50px;
height: 50px;
background: green;
animation: anim 10s linear;
}
@keyframes anim {
to {
transform: translate(120px,0);
}
}
<div class="animate"></div>