【问题标题】:How to start css animation on click and run the animation reversed on second click?如何在单击时启动 css 动画并在第二次单击时反转运行动画?
【发布时间】:2025-12-11 01:10:01
【问题描述】:

我正在尝试创建一个动画汉堡菜单。我发现了 CSS 动画并决定使用它。

菜单的设置非常简单:我有一个背景颜色和组成汉堡菜单的两个 div。

我创建了一个方形 div,并将其放置在菜单的右上角。我现在的目标是当我点击这个按钮时背景会淡入。该按钮现在是绿色的,但这是暂时的。当我现在如何开始点击动画时,我将为菜单的其余部分设置动画。

我已经尝试了很多来解决这个问题,但它就是不起作用。我希望你可以帮助我!

下面的代码是我现在拥有的代码。我没有添加与这个问题不太相关的代码。

当我再次单击按钮时菜单也应该关闭,因此动画应该反向运行。我怎样才能最好地做到这一点?

谢谢!拉尔夫

index.html

</div>
    <div class="dsgn-header">
        <div class="dsgn-header-menu-opened">
            <div class="dsgn-header-menu-opened-background"></div>
            <div class="dsgn-header-menu-opened-menuitems"></div>
        </div>

    <div class="dsgn-header-logo">
        <p class="dsgn-header-title">Site title</p>
    </div>
    <div class="dsgn-header-menu-mobile">
        <div class="dsgn-header-rectangle-up"></div>
        <div class="dsgn-header-rectangle-down"></div>
    <div class="dsgn-header-button" onclick="ani()" ></div>
</div>

header.css

.dsgn-header {
  width: 100vw;
  height: 88px;
  margin-left: 0px;
  background-color: white;
}



/* Logo */

@media (max-width: 350px) {
  .dsgn-header-logo {
    position: absolute;
    left: 16px;
    top: 27px;
  }
}
@media (min-width: 351px) {
  .dsgn-header-logo {
    position: absolute;
    left: 28px;
    top: 27px;
    width: 75%;
    max-width: 500px;
  }
}

.dsgn-header-title {
  color: #FF0000;
  font-size: 28px;
  font-family: 'Playfair Display', serif;
}


/* Menu animation */

.dsgn-header-rectangle-up {
  position:absolute;
  width:40px;
  height:1px;
  background:grey;
  right:28px;
  top:40px;
  -webkit-animation-name: example; /* Safari 4.0 - 8.0 */
  -webkit-animation-duration: 1s; /* Safari 4.0 - 8.0 */
  animation-name: dsgn-header-rectangle-up;
  animation-duration: 1s;
}

.dsgn-header-rectangle-down {
  position:absolute;
  width:40px;
  height:1px;
  background:grey;
  right:28px;
  top:54px;
  -webkit-animation-name: dsgn-header-rectangle-down; /* Safari 4.0 - 8.0 */
  -webkit-animation-duration: 1s; /* Safari 4.0 - 8.0 */
  animation-name: dsgn-header-rectangle-down;
  animation-duration: 1s;
}

/* Safari 4.0 - 8.0 */
@-webkit-keyframes example {
  0%   {background-color:red; left:0px; top:0px;}
  100% {background-color:red; left:0px; top:0px;}
}

/* Let op de ease in ease out en de animation iteration */


/* Menu opened */

.dsgn-header-menu-opened-background-active {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 100vw;
  height: 100vh;
background-color: black;
 -webkit-animation-name: menu-background; /* Safari 4.0 - 8.0 */
  -webkit-animation-duration: 1s; /* Safari 4.0 - 8.0 */
  animation-name: menu-background;
  animation-duration: 1s;
}


/* Safari 4.0 - 8.0 */
@-webkit-keyframes menu-background {
  0%   {
opacity: 0;
}
  100%   {
opacity: 1;
}
}

/* Standard syntax */
@keyframes menu-background {
  0%   {
opacity: 0;
}
  100%   {
opacity: 1;
}
}



.dsgn-header-menu-opened-menuitems {
  position: absolute;
  left: 45px;
  top: 150px;
  width: 75%;
  background-color: grey;
}

.dsgn-header-button {
position: absolute;
top: 0px;
right: 0px;
width: 88px;
height: 88px;
background-color: green;
}

Javascript:

$('#dsgn-header-button').onClick(function(){
    $('#dsgn-header-menu-opened-background').addClass('.dsgn-header-menu-opened-background-active');
});

【问题讨论】:

    标签: css css-animations


    【解决方案1】:

    如果你真的想做这个可逆动画,我建议你使用transition而不是keyframes,因为当你启动animation时,没有办法跟踪当前状态和目标状态,所以如果你在动画未完成时点击按钮,它会直接跳到最后一帧并反向播放。

    但是,解决方案如下:

    const demo = document.querySelector('.demo');
    const button = document.querySelector('button');
    
    let reverse = false;
    
    button.addEventListener('click', onClickPlay);
    
    function onClickPlay(){
      // Save the animation state
      let animation = demo.style.animation;
      
      // Clear the animation
      demo.style.animation = 'none';
      
      // You need to call this at next draw call to make the animation take effects
      setTimeout(()=>{
        // Restore the animation
        demo.style.animation = animation;
        // Make the animation running
        demo.style.animationPlayState = 'running';
        // Set the animation direction by current state
        demo.style.animationDirection = reverse ? 'reverse' : 'normal';
        // Flip the state
        reverse = !reverse;
        button.innerText = reverse ? 'Reverse' : 'Forward';
      }, 0);
    }
    @keyframes anim {
      0% {
        width: 0px;
        background-color: red;
      }
      
      100% {
        width: 100px;
        background-color: blue;
      }
    }
    
    .demo {
      /* Make the animation paused at the beginning */
      animation: anim 1s paused both;
      width: 0px;
      height: 20px;
    }
    <button>Forward</button>
    <div class="demo"><div>

    【讨论】:

    • 谢谢!这行得通。只有一件事不起作用。我删除了
    • 好吧,真的不知道那里发生了什么。但是您不应该直接使用此代码;这只是概念。也许您可以通过 CodePen 或 jsfiddle 向我展示代码,以便我提供帮助:/
    • 嗨!我把它放到这个 JSFiddle jsfiddle.net/ralphsmit/gs97x6n5/10 中。请尝试更改右边:0px;向左:0px;对于 .buttondemo 类。然后你就会明白我的意思了。感谢您花时间帮助我?
    • 这是你想要做的吗? jsfiddle.net/wheatup/ev1t0wx4/2如果是那种简单的动画,可以用transition实现,更简单,更好看:jsfiddle.net/wheatup/j8msh17p/4
    • 这确实是我想要的。我还希望两个小矩形旋转成十字形,用于汉堡菜单。我想我自己可以做到!谢谢你的帮助!你做了什么来解决我遇到的问题?