移动端弹性滑动以及滑动出界解决方案

移动端开发经常会遇到两个问题,滑动不灵敏,滑动到哪里就到哪里,这就是常说的:弹性滑动。在一个就是移动开发在真机中经常会遇到滑动出界从而能看见浏览器的背景了,这个在微信是非常常见的。先就这几个问题做一个总结:

  首先要搞明白两个概念

1、全局滑动:

  滚动条在body节点或者更高层。

2、局部滚动

  滚动条在body节点下边的某一个dom节点上。例如:页面有头部和底部固定的。

  弄清楚这两个概念还要了解在安卓和ios上这几个问题的解决都是不一样的。

一、首先说滑动不流畅这个问题:

  ios:全局滚动:默认支持

      局部滚动:默认没有滚动条,兵并且滑动会比较干涩。

Ios的解决办法是
body{
    -webkit-overflow-scrolling: touch;
}
/* 局部滚动的dom节点 */
dom{
    overflow: auto;
}

 

 建议将属性挂在body上,可以便秘很多奇怪的bug。

安卓下:

perfectscrollbariOS滑动 滑动设置在哪里_解决方案

 

二、滚动出界

  首先说几种出界滚动的情况

perfectscrollbariOS滑动 滑动设置在哪里_弹性滑动_02

 ios下:

  a、局部滚动中的解决方案为:

perfectscrollbariOS滑动 滑动设置在哪里_解决方案_03

上边的代码是这个组件的核心思想,也就是在滚动的开始的时候判断:如果是顶部的话就让页面向下滚动1px,如果是页面的底部的话就让向上滚动1px。

局部滚动中一定会有固定区域例如底部或者顶部,他们俩有时候滑动也回出现出界,解决方案为:页面的固定区域禁止touchmove默认事件。

<div onTouchmove={this.touchmove.bind(this)} ></div>

touchmove(event){
  event.stopPropagation();
  event.nativeEvent.stopImmediatePropagation(); }

 但是注意:

  但是这个库一定要谨慎用。因为他监听了touchstart事件,这个事件会使滚动滞后(在这里并不明显),passive event listeners。当然你不能用文章里的解决方法,否则如果你快速滑动,由于touchstart事件的监听函数还没执行到就已经开始滚动了所以可能还是会发生上面的情况,ScrollFix这个库就无效了。

 

补充一个情况

  这个坑就是你的内容不满视窗一个屏幕的时候,你向上滑动你会发现整个视窗都动了,也就成了全局滚动。这个现象是正常的,内容都不满一屏当然不需要滚动啊,甚至连滚动条都没产生。

  理由也说了,内容不足一个屏幕产生的现象,那么让内容时刻保持在一屏之上不就可以了。代码地址为

http://link.zhihu.com/?target=https%3A//github.com/fa-ge/LocalScrollFix

贴一下核心代码

update() {
      //当内容超过一屏的时候isArrived为true
        if (this.isArrived) {
            return
        }
      //每次调用update方法时候都去更新fixDom的paddingTop值
        const fixDomPaddingTop = this.computerFixDomPaddingTop()

        if (fixDomPaddingTop >= 0) {
              //只有当计算后的值大于0才要更新
            this.fixDom.style.paddingTop = `${fixDomPaddingTop + 2}px`
        } else {
          //当计算后的值小于0的时候,也就是原来的内容就超过一屏幕了。arrived方法中会把fixDom移除。
            this.arrived()
        }
    }
    //计算fixDom所需要的paddingTop值
    computerFixDomPaddingTop() {
          //fixDom指的是append到最底部的dom。win指的是视窗
        const {fixDom, win} = this
        //一开始想内容的高度+paddingTop==数创的高度。因为直接求内容的高度其实并不简单。
        //所以稍微变通了以下,让窗口的top值减去fixDom的top值其实就是fixDom的paddingTop值
        //在把视窗的borderBottomWidth和视窗的paddingBottom考虑进去
        const fixDomTop = fixDom.getBoundingClientRect().top
        const winBottom = win.getBoundingClientRect().bottom
        const {paddingBottom: winPaddingBottom, borderBottomWidth: winBorderBottomWidth}= window.getComputedStyle(win, null)
        return winBottom - parseFloat(winPaddingBottom) - parseFloat(winBorderBottomWidth) - fixDomTop
    }

 

b、全局滚动:

 

  暂时还没有解决方案,所以实在想避免这个的话,可以将全局滚动改变为局部滚动的布局。这个实现起来方法很多。

 

perfectscrollbariOS滑动 滑动设置在哪里_移动开发_04

 

 

 

 

安卓的局部滚动很蛋疼

 

  安卓的局部滚动会导致滚动条显示不流畅,且滚动不流畅。所以建议安卓下只是用全局滚动。

 

安卓下局部滚动改变为全局滚动的思路为:

 

 

perfectscrollbariOS滑动 滑动设置在哪里_ios_05

 

 

流畅滚动的几条方法

 

   1、body上加上

-webkit-overflow-scrolling: touch;

2、ios下尽量使用局部滚动。
3、ios下引入scrollfix避免出界。
4、安卓下尽量使用全局滚动。
  a、尽量不用overflow: auto;
  b、使用 Min-height: 100%; 代替 height: 100%;
5、ios下带有滚动条且position: absolute;的节点不要设置背景色。