IOS移动端滚动问题之-webkit-overflow-scrolling

-webkit-overflow-scrolling

1.概述

1.1 定义

属性控制元素在移动设备上是否使用滚动回弹效果

1.2 取值

  • auto:使用普通的滚动效果。当手指从设备的触摸屏上离开时,滚动会立即停止
  • touch:使用具有回弹效果的滚动。当手指从设备的触摸屏上离开时,滚动区域的内容会继续保持一段时间的滚动,且继续滚动的速度与时间与手势滑动的剧烈程度成正比。

2.浏览器兼容性

-webkit-overflow-scrolling 属性的浏览器兼容性请参考 CanIUse

3.使用场景

在IOS移动端上,当使用overflow: scroll;属性时,滚动效果慢且不流畅,该情况可以使用

-webkit-overflow-scrolling: touch;属性,让滚动条产生回弹效果,增加滚动的流畅性,提高用户的体验。

4.问题

当页面滑动至底部(顶部暂未发现)时,当回弹效果结束的瞬间,继续上拉让页面向下滚动,会导致滚动区域卡住不动,且一段时间后自动恢复正常。该属性包含多种问题但不仅限于以上一种。

5.解决方案

5.1 原理

在手指在移动设备的触摸屏上滑动的过程中,监听手指开始滑动,滑动过程中及滑动结束3个事件。在滑动中事件中检查当前滑动的位置是否到达滚动区域的底部,若已到达底部则停止滑动。

5.2 实现

给滑动区域添加手势触摸的相关事件

<div @touchstart="touchStart" @touchmove="touchMove" @touchEnd="touchEnd">
  <!-- 这是一个滚动区域 -->
</div>

定义一个变量用来记录上一次手势滑动过程中最新位置的纵坐标值

export default {
  data () {
    lastScrollY: 0 // 上一次手势滑动过程中最新位置的纵坐标
  }
}

通过手势滑动过程中出发的事件监听滚动区域是否已经到达底部

export default {
  methods: {
    touchStart(e) {
      // 滑动开始时记录起始位置纵坐标
      this.lastScrollY = e.touches[0].clientY
    },
    touchMove(e) {
      // 滑动过程中记录当前位置纵坐标
      let top = e.touches[0].clientY
      // 当前滚动条距离顶部的距离
      let scrollTop = e.currentTarget.scrollTop
      // 判断滚动条滚动的方向
      let direction = (this.lastScrollY - top) < 0 ? 'up' : 'down'

      // (若滚动条距离顶部的距离 >= 滚动区域的高度 - 滚动可视区域的高度) && 滚动条滚动方向向下 :已到达滚动区域的底部
      if (scrollTop >= (e.currentTarget.scrollHeight - e.currentTarget.offsetHeight) && direction === 'down') {
        // 取消事件的默认行为
        e.preventDefault()
        // 还原记录的坐标值
        this.lastScrollY = 0
      } else {
        // 否则更新记录的当前位置纵坐标
        this.lastScrollY = top
      }
    },
    touchEnd() {
      // 每一次滑动结束时还原记录的坐标值
      this.lastScrollY = 0
    }
  }
}
posted @ 2020-08-31 21:00  jeff_chang  阅读(841)  评论(0编辑  收藏  举报