css3使用animation实现消息轮播在iOS中的bug

环境

  • iOS 11
  • Vue2.x
  • 在PC端Chrome调试没问题、Android端没问题
  • 刚来公司第二天就安排修bug了

bug重现

源码

<template>
  <div class="carousel">
    <div class="scroll-wrapper">
      <span
        v-for="(item, index) in list"
        :class="['scroll-item']"
        :key="index"
      >
      恭喜{{item.mobile}}&nbsp;&nbsp;抽中&nbsp;<em class="prize">{{item.prizeName}}</em>
      </span>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'ScrollMessage',

    props: {
      list: Array
      /* 备注:
        1. 默认下会设置五个写死的数据
        2. 如果登录之后,会向后台拿真实数据,取前十条
      */
    }
  }
</script>

<style lang="less" scoped>
.carousel {
  position: relative;
  margin-top: 0.4rem;
  padding: 0 0.2rem;
  border: 1px dashed #d28c5a;
  height: 0.75rem;
  line-height: 0.75rem;
  background: #6f09d4;
  // overflow: hidden;
}
.scroll-wrapper {
  position: absolute;
  white-space: nowrap;
  animation: scroll 30s linear infinite;
}
.scroll-item {
  display: inline-block;
  vertical-align: middle;
  margin-right: 0.4rem;
  font-size: 0.24rem;
  color: #fff;
  background: yellowgreen;
  .prize {
    color: #feb533;
    font-style: normal;
  }
}
@keyframes scroll {
  0% {
    -webkit-transform: translateX(0);
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -o-transform: translateX(0);
    transform: translateX(0);
  }

  100% {
     -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);	
  }
}
</style>

复制代码

登录前:默认下会设置五个写死的数据。正常(不放图啦)

图2-登录后:向后台拿真实数据,取前十条。轮播卡顿问题

图3-登录后刷新页面:不轮播了,切换tab后回到页面才轮播

定位bug之旅

  1. 经验之谈。看到动画效果卡顿,一下子就想到了开启css3硬件加速。加了属性之后还是没效果。
  2. 行为观察。登录后动画才会卡。登录后向后台拿真实数据,取前十条。
  3. 大胆猜测。数据的变化,引起scroll-wrapper总长度的变化。总长度的变化需要重新计算动画效果。iOS在这里没有处理好。
  4. 验证。登录后,把数据写死成登录前默认的五条,效果正常。把数据写成6条,效果不正常。把数据写死成登录前默认的五条,只改变手机尾号,效果正常。验证成功!

我的解决方案

在登录后,让动画重新播放。关于如何实现重新播放,可以参考这里。其实就是再多加一个动画frame和类。

解决方案代码

<template>
  <div class="carousel">
    <div class="scroll-wrapper" :class="{'play': list.length === 5, 'play2': list.length > 5}">
      <span
        v-for="(item, index) in list"
        :class="['scroll-item']"
        :key="index"
      >
      恭喜{{item.mobile}}&nbsp;&nbsp;抽中&nbsp;<em class="prize">{{item.prizeName}}</em>
      </span>
    </div>
  </div>
</template>
<script>
...
</script>
<style lang="less" scoped>
...
.scroll-wrapper {
  position: absolute;
  white-space: nowrap;
  -webkit-transform: translateX(0);
  -moz-transform: translateX(0);
  -ms-transform: translateX(0);
  -o-transform: translateX(0);
  transform: translateX(0);

  &.play{
    animation: scroll 30s linear infinite;
  }

  &.play2{
    animation: scroll2 30s linear infinite;
  }
}
...
@keyframes scroll {
  0% {
    -webkit-transform: translateX(0);
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -o-transform: translateX(0);
    transform: translateX(0);
  }

  100% {
     -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);	
  }
}

/* to fix bug: after login, animation problem */
@keyframes scroll2 {
  0% {
    -webkit-transform: translateX(0);
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -o-transform: translateX(0);
    transform: translateX(0);
  }

  100% {
     -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);	
  }
}
</style>
复制代码

有更好的解决方案欢迎补充哟。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值