我如何触发css动画多次使用javascript和反应在一个最佳的方式?



我创建了一个react组件,它由一个3d立方体(使用css)和两个旋转该立方体90度的按钮组成(一个按钮向左旋转,另一个按钮向右旋转)

import React from 'react';
import './App.css';
function App() {
const rotateLeft = async (event) => {
event.preventDefault();
const boxArea = document.getElementsByClassName("box-area")[0];
const newNode = boxArea.cloneNode(true);
boxArea.classList.add('rotateLeft');
setTimeout(function(){
boxArea.parentNode.replaceChild(newNode, boxArea);
}, 3005)
};
const rotateRight = async (event) => {
event.preventDefault();
const boxArea = document.getElementsByClassName("box-area")[0];
const newNode = boxArea.cloneNode(true);
boxArea.classList.add('rotateRight');
setTimeout(function(){
boxArea.parentNode.replaceChild(newNode, boxArea);
}, 3005)
};
return (
<div className="App">
<div className="hexagon-panel">
<div className="wrapper">
<div className="box-area">
<div className="box front"/>
<div className="box back"/>
<div className="box left"/>
<div className="box right"/>
</div>
</div>
<div className="hexagon-actions">
<button onClick={rotateLeft}>Left</button>
<button onClick={rotateRight}>Right</button>
</div>
</div>
</div>
);
}
export default App;
如您所见,我通过添加类来触发动画,我等了3秒多一点(动画持续3秒),然后用一个不包含类的节点替换节点。

一个更好的解决方案(但我也不喜欢它)是在动画结束后删除类。

const rotateLeft = async (event) => {
event.preventDefault();
const boxArea = document.getElementsByClassName("box-area")[0];
boxArea.classList.add('rotateLeft');
setTimeout(function(){
boxArea.classList.remove('rotateLeft');
}, 4000)
};

但我不相信。这样做的原因是setTimeout,因为它是一个全局函数,我害怕内存泄漏(即使它是一个小的)。每次点击调用一个新的setTimeout,并且不擦除前一个。

我正在考虑这个

const rotateLeft = async (event) => {
event.preventDefault();
const boxArea = document.getElementsByClassName("box-area")[0];
boxArea.classList.add('rotateLeft');
const func = setTimeout(function(){
boxArea.classList.remove('rotateLeft');
}, 4000)
clearTimeout(func);
};

但我不知道这是否有意义。

有没有一种更好的方法来删除类不使用setTimeout?或者在需要它的情况下,删除它是一个好的实践吗?

感谢您的宝贵时间!

您可能正在寻找这个:使用动画事件。它包括在动画结束时触发的animationend事件。

或者在将来,你可以使用Web Animations API,一旦它被广泛实现。

或者如果你想坚持使用setTimeout,只需在开始动画之前放入清理代码(clearTimeout, remove class等)。这样,你总是得到一个"干净"的状态。

最新更新