移动端滚动进阶

流畅滚动

IOS

  1. 建议使用局部滚动
  2. body标签里加上属性-webkit-overflow-scrolling:touch;实现弹性滚动
  3. 局部滚动的dom节点加上属性overflow:auto;

Android

  1. 只能实现全局滚动
  2. 标题栏和底部栏使用fixed进行定位
  3. 中间滚动部分使用padding填充标题栏和底部栏的固定部分,从而使局部滚动变成全局滚动

滚动出界问题

  1. 使用scrollFix避免滚动出界

    1
    2
    3
    4
    5
    6
    if(startTopScroll <= 0) {
    elem.scrollTop = 1;
    }
    if(startTopScroll + elem.offsetHeight >= elem.scrollHeight ) {
    elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
    }
  2. 当页面底部有固定部分时,禁止touchmove默认事件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function isPassive() {
    var supportsPassiveOption = false;
    try {
    addEventListener("test", null, Object.defineProperty({}, 'passive', {
    get: function () {
    supportsPassiveOption = true;
    }
    }));
    } catch(e) {}
    return supportsPassiveOption;
    }
    document.addEventListener('touchmove', function (e) { e.preventDefault(); }, isPassive() ? {
    capture: false,
    passive: false
    } : false);

滚动事件结束监听

1
2
3
4
5
6
7
8
let scrollTimer = null
function handler () {
console.log('滚动结束了')
}
document.addEventListener('scroll', () => {
clearTimeout(scrollTimer)
scrollTimer = setTimeout(handler, 250)
})

流畅滚动实践总结

  • body上加上 -webkit-overflow-scrolling: touch
  • IOS尽量使用局部滚动
  • IOS引入scrollFix避免滚动出界
  • IOS上position: absolute的dom节点不要设置背景色
  • Android尽量使用全局滚动,尽量不用overflow:auto, 使用min-height代替height