【问题标题】:Why does the drawer not animate on the way out?为什么抽屉在退出时没有动画?
【发布时间】:2021-11-21 14:25:49
【问题描述】:

我希望我的抽屉在进、出和动画结束时设置动画,转到display: none,但是当抽屉关闭时,它会消失并且不会出现动画。

const Drawer = ({ closeDrawer, isDrawerOpen }) => {
  const [isAnimating, setIsAnimating] = useState()
  let drawerClassName
  if (isDrawerOpen) {
    drawerClassName = "drawer-in"
  } else if (!isDrawerOpen && isAnimating) {
    drawerClassName = "drawer-animating"
  } else if (!isDrawerOpen && !isAnimating) {
    drawerClassName = "drawer-out"
  }
  return (
    <>
      <div
        className={`drawer ${drawerClassName}`}
        onAnimationStart={() => setIsAnimating(true)}
        onAnimationEnd={() => setIsAnimating(false)}
      ></div>
      <div onClick={closeDrawer}></div>
    </>
  )
}

CSS:

.drawer {
  height: 100%;
  width: 60%;
  background-color: #fff;
  position: absolute;
  right: 0;
  top: 0;
  opacity: 1;
  z-index: 3;
  transform: translateX(100%);
}

.drawer-in {
  animation: 0.7s drawerIn;
  transform: translateX(0);
  display: block;
}

.drawer-animating {
  animation: 0.7s drawerOut;
  display: block;
}

.drawer-out {
  animation: 0.7s drawerOut;
  display: none;
}

@keyframes drawerIn {
  0% {
    transform: translateX(100%);
  }
  1% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(0);
  }
}

@keyframes drawerOut {
  0% {
    transform: translateX(0);
  }
  99% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(100%);
  }
}

【问题讨论】:

  • 可能是因为 Drawer 在调用 {closeDrawer} 后立即关闭。也许你需要添加 setTiomeout 然后调用它。

标签: javascript css reactjs animation


【解决方案1】:

这是因为当您将drawer-out 类设置为元素时,display: none; 立即被激活并且您看不到动画。
一种解决方案是在 JavaScript 中运行 setTimeout 函数以等待动画完成,然后将元素显示属性更改为 none。这将允许您的“关闭动画”在移除元素之前完成。有关工作示例,请参见下面的我的 sn-p。

基本上,在我的示例 sn-p 中发生的事情是我通过添加与动画关联的类来触发关闭动画。然后我设置了一个等待动画完成的超时功能(以毫秒为单位设置超时以匹配您的 CSS 中的动画时间)。超时完成后,动画类被移除,元素的数据属性设置为closed,这将触发显示无。希望这会有所帮助。

const menu = document.querySelector('.menu');
const menuToggle = document.querySelector('.menu_toggle');
menuToggle.checked=false

menuToggle.addEventListener('change',(e)=>{
    menuToggle.disabled=true
    let menuState = menu.dataset.menuState
    if(menuState==='closed'){
        menu.dataset.menuState='opened'
        setTimeout(() => {
            menuToggle.disabled=false
        }, 500);
    }else{
        menu.classList.add('animate_close')
        setTimeout(() => {
            menu.classList.remove('animate_close')
            menu.dataset.menuState='closed'
            menuToggle.disabled=false
        }, 500);
    }
})
body {
    background-color: rgb(235, 235, 235);
}

.menu {
    background-color: black;
    color: white;
    width: fit-content;
}
.menu {
    transition: all .5s ease-in-out;
}

.menu[data-menu-state="closed"] {
    background-color: red;
    display: none;
}
.menu[data-menu-state="opened"] {
    animation: openMenu .5s ease-in-out;
    transform: translateX(100%);
    background-color: green;
}
.menu.animate_close{
    background-color: rgb(0, 30, 128);
    animation: closeMenu .5s ease-in-out;
    opacity: 0;
}

@keyframes openMenu {
    0% {
        transform: translateX(0);
    }

    100% {
        transform: translateX(100%);
    }
}

@keyframes closeMenu {
    0% {
        transform: translateX(100%);
    }
    100% {
        transform: translateX(0);
      
    }
}
<body>
    <label for="menu_toggle">Menu Toggle</label>
    <input id="menu_toggle" type="checkbox" class="menu_toggle">
    <div class="menu_container">
        <div class="menu" data-menu-state="closed">
            <ul>
                <li>Item1</li>
                <li>Item2</li>
                <li>Item3</li>
            </ul>
        </div>
        
    </div>
   
    <script src="main.js"></script>
</body>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多