0

我不确定这是否是问这个问题的合适地方;我考虑过软件推荐,但我想我会先在这里试一试。

我正在创建一个 PWA,并且在每次迭代中,我真的很想专注于让它看起来/感觉不那么笨拙和尽可能平滑。好吧,就像一个原生应用程序。

所以这就是问题所在——我正在使用 Semantic-UI-React 提供的转换(动画),虽然当一个元素占据它的空间时它工作得很好,但我想知道是否有一种做法或模式来处理与正在动画的元素相邻的 DOM 元素?

我在下面提供了一个 GIF 来说明我的意思。我想我可以将动画元素移出表单的容器以防止卡顿,但我想知道是否有更优雅的模式或方法来解决这个问题......

谢谢!

在此处输入图像描述

4

1 回答 1

1

不幸的是,对此没有特别优雅的方法。

关于帖子标题中的问题,一种常见的方法是对height新元素进行动画处理。如果您不知道元素的高度,不幸的是,动画 from 0pxtoauto 尚未起作用,但您可以通过将max-heightfrom动画0px设置为略大于您期望元素的最大尺寸的值来伪造它。

但不要那样做。

它将导致浏览器在每个动画帧上布局页面,并且几乎肯定会在低端设备上卡顿。

相反,您最好制作动画transform

最常见的方法是:

  1. 在将新元素添加到 DOM之前getBoundingClientRect()获取将受到影响的元素的原始位置(使用等)(可能使用,除非您使用钩子,在这种情况下,您可以使用类似的效果)。getSnapshotBeforeUpdateuseRef

  2. 添加新元素后(您可能还通过使用transform合适的scale()函数对其进行动画处理),计算偏移元素现在所在位置与它们过去所在位置相比的增量。

  3. 设置transform从增量的负值到零的动画(即 FLIP 方法)。例如,如果元素已在页面下方移动了 300px,则动画transformtranslateY(-300px)none

当然,您需要对流中受影响的所有元素执行此操作,因此将它们全部放在一个容器中并为其设置动画可能是最简单的。

关于第三点,您有几种技术选择,但都不是很好:

  • CSS 过渡。这些是最简单的,但您必须触发样式刷新才能使负增量起点保持不变。例如

    elem.style.transform = `translateY(-${offset}px)`;
    elem.style.transition = `transform .3s`;
    getComputedStyle(elem).transform; // Flush style
    elem.style.transform = `none`;
    
  • CSS 动画。使用 CSSOM 动态生成@keyframes规则是一件痛苦的事情,但至少您不需要触发样式刷新(并且您可以为方便设置一个带有隐式 to-keyframe 的动画)。

    @keyframes random-id { from: { translateY(-300px); } }
    
  • 网络动画。这可能是最合适的。

    elem.animate({ transform: [ `translateY(-${offset}px)`, 'none' ] }, 300);
    
    // In future when browsers ship support for implicit to/from keyframes:
    elem.animate({ transform: `translateY(-${offset}px)`, offset: 0 }, 300);
    

    不幸的是,Safari 在 Tech Preview 中仅支持 Web 动画,因此 Safari 用户将在下一个 Safari 版本之前获得非动画版本。在基于 Chromium 的 Edge 发布之前,Edge 用户还将获得非动画版本。也有一个polyfill,但目前还没有积极维护。

如果你使用 React,Animating the Unanimatable是一篇很有帮助的文章。

另一个棘手的部分是确保滚动不会跳转,您可能需要查看滚动锚定。

于 2019-04-12T01:16:56.197 回答