是否可以对菜单的打开和关闭进行动画处理?菜单节点在打开/关闭时被删除或附加到DOM树,因此这会干扰CSS动画。有没有解决的办法?
答案 0 :(得分:3)
要打开动画,这是相对容易的,只需要使用css将动画添加到<Menu/>
组件中即可。
以下示例使用淡入/淡出动画
@keyframes fadeIn {
0% {
opacity: 0;
transform: translateY(2rem);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.menu {
animation: fadeIn 0.2s ease-in-out;
}
在您的渲染方法中
<Select
{...}
components={{
Menu: (props) => <components.Menu {...props} className="menu" />
}}
/>
结束动画有点棘手,因为API支持有限。当菜单关闭事件触发时,菜单元素将立即被删除,没有时间运行关闭动画。
因此,我们需要稍微更改关闭事件的行为。策略是让菜单突然像往常一样关闭。但是在此之前,我们将对菜单进行另一个克隆,然后该克隆将运行结束动画并在动画结束时将其自身删除。
// generate unique ID for every Select components
const uniqueId = "select_" + Math.random().toFixed(5).slice(2);
return (
<Select
id={uniqueId}
onMenuClose={() => {
const menuEl = document.querySelector(`#${uniqueId} .menu`);
const containerEl = menuEl?.parentElement;
const clonedMenuEl = menuEl?.cloneNode(true);
if (!clonedMenuEl) return; // safeguard
clonedMenuEl.classList.add("menu--close");
clonedMenuEl.addEventListener("animationend", () => {
containerEl?.removeChild(clonedMenuEl);
});
containerEl?.appendChild(clonedMenuEl!);
}}
{...}
/>
);
不要忘记将结束动画附加到正确的CSS类。在这种情况下,menu--close
@keyframes fadeOut {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(2rem);
}
}
.menu--close {
animation: fadeOut 0.2s ease-in-out;
}
最后,您将得到类似的东西
答案 1 :(得分:0)
另一种方法是使用 menuIsOpen 道具而不是克隆。
const [isMenuOpen, setIsMenuOpen] = useState(false)
const openMenuHandler = async () => {
await setIsMenuOpen(true)
const menu = document.querySelector(`#select .menu`)
menu.style.opacity = '1'
}
const closeMenuHandler = () => {
const menu = document.querySelector(`#select .menu`)
menu.style.opacity = '0'
setTimeout(() => {
setIsMenuOpen(false)
}, 400)
}
<Select
menuIsOpen={isMenuOpen}
onMenuOpen={() => {openMenuHandler()}}
onMenuClose={() => {closeMenuHandler()}}
/>