为什么我的简单 CSS 过渡动画在智能手机上不流畅?

Why is my simple CSS transition animation jerky on smartphones?

为了让我的手机菜单动画更流畅,being advised从jQuery动画切换到CSS动画后,我仍然发现手机菜单打开的动画是智能手机很不稳定,我不知道如何改进它。

JS:

$( '.header__menu_icon' ).click(function() {
  var allClasses = 'right_0 right_280 right_minus_280';
  $( '.mobile_menu, .wrap' ).removeClass( allClasses );
  if ( $('.wrap' ).css( 'right' ) == '0px' ) { 
    $( '.wrap' ).addClass( 'right_280' ); 
  }
  else { 
    $( '.wrap' ).addClass( 'right_0' ); 
  }
});

CSS:

.mobile_menu {
  width: 280px;
  position: absolute;
  right: -280px;
}
.right_0 {
  right: 0 !important;
}
.right_280 {
  right: 280px !important;
}
.right_minus_280 {
  right: -280px !important;
}
body,
.wrap,
.mobile_menu {
  transition: all 0.2s ease-in-out;
}

HTML:

<body>
<div class='wrap'>
  <div class='header'>
    <div class='mobile_menu'>
      ...
    </div>
  </div>
</div>
</body>

编辑: 基于@GaijinJim 下面的回答的新代码。

JS:

$( '.header__menu_icon' ).toggle( function() {
  $( '.wrap' ).removeClass( 'mobile_menu_opening mobile_menu_closing' );
  $( '.wrap' ).addClass( 'mobile_menu_opening' ); 
}, function() {
  $( '.wrap' ).removeClass( 'mobile_menu_opening mobile_menu_closing' );
  $( '.wrap' ).addClass( 'mobile_menu_closing' ); 
});

CSS:

@keyframes mobile_menu_opening {
  0% { 
    transform: translateX(0px); 
  }
  100% { 
    transform: translateX(-280px); 
  }
}
@keyframes mobile_menu_closing {
  0% { 
    transform: translateX(-280px); 
  }
  100% { 
    transform: translateX(0px); 
  }
}
.mobile_menu_opening {
  animation-name: mobile_menu_opening;
  animation-duration: 2s;
}
.mobile_menu_closing {
  animation-name: mobile_menu_closing;
  animation-duration: 1s;
}
.wrap {
  position: relative;
}

这听起来更像是性能问题,因为您没有使用转换。

已在 Chris CoyierA Tale of Animation Performance 中提到

It has become common generic advice that using translate() to move elements has better performance than using top/right/bottom/left.

[...]Paul talked to another Paul on the Chrome Team, Paul Lewis, who agreed that it is "smarter to use translate() for design-y motion." But went on to say that there is more to this than frame rate. With translate(), you get sub-pixel animation which is a kind of blurring between pixels that usually leads to smoother animation

您还可以阅读这篇关于 All you need to know about CSS Transitions 的精彩文章:

Hardware acceleration
Transitioning certain properties, such as left and margin causes the browser to recalculating styles every frame. This is fairly expensive, and can lead to unnecessary re-paints, especially if you have a lot of elements on the screen. This is especially noticeable in less powerful devices, such as mobiles.

This solution is to offload the rendering to the GPU using CSS transformations. In simple terms, this turns the element into an image during the transition, avoiding any style recalculations which greatly increases performance.

所以在你的情况下,我会改变你的整个 classes,它们在所有应有的尊重中有点混乱,像一个简单的动画:

@keyframes buttonInOutAnimation{
    0%{transform:translateX(-280px);}
    50%{transform:translateX(280px);}
    100%{transform:translateX(-280px);}
}

然后您可以将此动画分配给您的按钮 class,如下所示:

.YourClassToAnimate{
    animation: buttonInOutAnimation 1s ease-in-out 0s 1;
}

然后您可以像之前一样将此 class 分配给 jquery。

最后一件事: 在您的情况下,您需要添加填充模式以在动画结束时冻结动画状态。

-webkit-animation-fill-mode: forwards; 

forwards 使动画保持最后一帧的状态。
backwards 将动画留在开头