浏览器CSS动画没有立刻加载,只有鼠标移动才会加载?

我的目的是生成一个堆叠卡片的翻页组件,使用translate3d产生堆叠效果,但是在浏览器中堆叠部分总会被hidden。

后来我发现浏览器一开始没有加载CSS动画。但是当我鼠标在目标元素上进行移动后,才会加载出来CSS动画,然后堆叠被hidden部分就显示了。

js添加动画是在加载的时候。我在JS逻辑代码外部添加了判断,在代码块里添加了控制台打印。加载的时候打印了数据,但是移动的时候并没有打印出内容。添加动画确实是在一开始就有的,但是鼠标移动到目标元素上并没有执行css,这我就很奇妙啦

slidecard.vue:

  • 主要是一个可拖拽的翻页组件,模仿其他人做的。
<ul
    class="stack column"
    ref="mySlideStack"
    @touchstart.stop.prevent="stop"
    @touchmove.stop.prevent="stop"
    @touchend.stop.prevent="stop"
    @touchcancel.stop.prevent="stop"
    @mousedown.stop.prevent="stop"
    @mouseup.stop.prevent="stop"
    @mousemove.stop.prevent="stop"
    @mouseout.stop.prevent="stop">
    <li
      class="stack-item"
      v-for="(item, index) in pages"
      :key="index"
      :style="transform(index)"
      @touchstart.capture.prevent="touchstart"
      @touchmove.capture.prevent="touchmove"
      @touchend.capture.prevent="touchend"
      @touchcancel.capture.prevent="touchend"
      @mousedown.capture.prevent="touchstart"
      @mouseup.capture.prevent="touchend"
      @mousemove.capture.prevent="touchmove"
      @mouseout.capture.prevent="touchend"
      @webkit-transition-end="onTransitionEnd"
      @transitionend="onTransitionEnd">
      <img :src="item">
    </li>
  </ul>

css代码(使用scss)

  • 使用perspective和translate3d实现堆叠效果
   .stack {
    position: relative;
    perspective: 1000px; //子元素视距
    touch-action: none;
    perspective-origin: 50% 150%; //子元素透视位置
    transform: translate3d(0px, 0px, 0px);
  }

  .stack-item {
    position: absolute;
    height: 100%;
    width: 100%;
    border-radius: 4px;
    text-align: center;
    overflow: hidden;
    user-select: none;
    opacity: 0;
    // 控制着用户能否选中文本
    img {
      width: 100%;
      height: 100%;
      // display: block;
      pointer-events: none;
    }
  }

js代码(大部分都是拖拽的其实不必太关注)

  • translate3d的值都是根据拖拽距离计算的,如何计算并不是重点不需要纠结。
// 计算出style
transform (index) {
  let tempdata = this.tempdata
  let currentPage = tempdata.currentPage
  let length = this.pages.length
  // 设置上一张
  let lastPage = currentPage === 0 ? length - 1 : currentPage - 1
  let style = {}
  let visible = tempdata.visible // 可见层数
  let transform = tempdata.prefixes.transform
  let transition = tempdata.prefixes.transition
  if (index === currentPage) { // 首页样式
    style[transform] = `translate3d(${tempdata.poswidth}px, ${tempdata.posheight}px, 0px) rotate(${tempdata.rotate}deg)`
    style['opacity'] = tempdata.opacity
    style['zIndex'] = 10
    if (tempdata.animation) {
      style[transition + 'TimingFunction'] = 'ease'
      style[transition + 'Duration'] = tempdata.animation ? '300ms' : '0ms'
    }
  } else if (this.findStack(index, currentPage)) { // 显示中图片
    let perIndex = index - currentPage > 0 ? index - currentPage : index - currentPage + length // 和前面间隔层数
    style['opacity'] = '1'
    // 根据划出比例
    style[transform] = `translate3d(0, 0, ${-1 * 60 * (perIndex - this.offsetRatio) / this.px2rem}rem)`
    style['zIndex'] = visible - perIndex
    if (!tempdata.tracking) {
      // 兼容前缀
      style[transition + 'TimingFunction'] = 'ease'
      style[transition + 'Duration'] = '300ms'
    }
  } else if (index === lastPage) { // 设置翻过去的页的动画效果
    style[transform] = `translate3d(${tempdata.lastPosWidth}px, ${tempdata.lastPosHeight}px, 0px) rotate(${tempdata.lastRotate}deg)`
    style['opacity'] = tempdata.lastOpacity
    style['zIndex'] = tempdata.lastZindex
    style[transition + 'TimingFunction'] = 'ease'
    style[transition + 'Duration'] = '300ms'
  } else {
    style['zIndex'] = '-1'
    style[transform] = `translate3d(0, 0, ${-1 * visible * 60 / this.px2rem}rem)`
  }
    return style
},
    
// 鼠标移动或者触摸事件,判断只有拖拽的时候才执行代码块,所以鼠标单纯移动过并不会生效
touchmove (e) {
  // 记录滑动位置
  if (this.tempdata.tracking && !this.tempdata.animation) {
    if (e.type === 'touchmove') { // 判断电脑和手机
      this.basicdata.end.x = e.targetTouches[0].clientX
      this.basicdata.end.y = e.targetTouches[0].clientY
    } else {
      this.basicdata.end.x = e.clientX
      this.basicdata.end.y = e.clientY
    }
    // 计算滑动值
    this.tempdata.poswidth = this.basicdata.end.x - this.basicdata.start.x
    this.tempdata.posheight = this.basicdata.end.y - this.basicdata.start.y
    // 计算翻转角度
    let rotateDirection = this.rotateDirection()
    let angleRatio = this.angleRatio()
    this.tempdata.rotate = rotateDirection * this.offsetWidthRatio * 15 * angleRatio
  }
}

实际上调用slidecard.vue的时候

  • slide-wrapper去除overflow:hidden的时候,堆叠也会显示????
<div id="slide-wrapper" class="column">
   <slide-card class="slide"></slide-card>
</div>

#slide-wrapper {
    width: 100%;
    height: 450px;
    overflow: hidden;
    justify-content: center;
    background-color: #565f77;
}
.slide {
    width: 320px;
    height: 320px;
}
阅读 2.2k
1 个回答

这就要看你js怎么写的了,也许你写的是鼠标移动到目标元素上,才会加载出来动画。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题