反应选择菜单打开/关闭的动画

Dmi*_*han 4 reactjs react-select

是否可以动画打开和关闭菜单?菜单节点在打开/关闭时被删除或附加到 DOM 树,因此这会干扰 css 动画。有解决办法吗?

Nea*_*arl 5

对于打开动画来说,相对容易,你只需要<Menu/>使用css将动画添加到组件中即可。

以下示例使用淡入/淡出动画

@keyframes fadeIn {
  0% {
    opacity: 0;
    transform: translateY(2rem);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

.menu {
  animation: fadeIn 0.2s ease-in-out;
}
Run Code Online (Sandbox Code Playgroud)

在您的渲染方法中

<Select
  {...}
  components={{
    Menu: (props) => <components.Menu {...props} className="menu" />
  }}
/>
Run Code Online (Sandbox Code Playgroud)

关闭动画有点棘手,因为 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!);
    }}
    {...}
  />
);
Run Code Online (Sandbox Code Playgroud)

不要忘记将关闭动画附加到正确的 css 类。在这种情况下menu--close

<Select
  {...}
  components={{
    Menu: (props) => <components.Menu {...props} className="menu" />
  }}
/>
Run Code Online (Sandbox Code Playgroud)

最后,你会得到这样的东西

在此处输入图片说明

现场演示

编辑 React-选择打开/关闭动画