JS控制页面滚动

前言

最近解决一个 wkwebview 的兼容性问题,需要JS控制页面的滚动,踩了不少坑。

通常我们控制页面滚动用到下面几个api

  • window.scrollTo(x,y)
  • window.scrollX/window.scrollY
  • window.pageYOffset/window.pageXOffset
  • document.documentElement.scrollTop
  • document.body.scrollTop

window.scrollTo(x,y)

设置页面滚动。IE9+ 、firefox、chrome,opera均支持该方式获取页面滚动高度值,忽略Doctype规则。

window.scrollX/Y

只读属性 firefox、chrome,opera支持,IE不支持,忽略Doctype规则

window.pageXOffset

只读属性 IE9+ 、firefox、chrome,opera均支持,忽略Doctype规则

document.documentElement 和 document.body(划重点)

网上清一色:使用DTD定义文档时(<!DOCTYPE ...>),使用document.documentElement,否则 使用document.body。除此之外,无其他兼容问题。
发现问题:公司ios移动端使用wkwebview,h5页面均定义DTD<!DOCTYPE html>,所以使用了document.documentElement.scrollTop。结果发现部分ios手机不兼容,比如:iphone xs 12.4.1使用document.body才可以。

至少得出结论:关于document.documentElementdocument.body,safari内核不符合DTD规则,某些版本仅支持document.body控制滚动

解决方案

  document.scrollingElement.scrollTop = 200 
  // 等价于
  document.documentElement.scrollTop = 200 
  document.body.scrollTop = 200 

Document.scrollingElement可以解决上述safari不兼容性问题, 而且更清爽。虽然这个APIIEie12-Edge才兼容,但是移动端使用不存在兼容性问题。

通用兼容性方案(支持桌面 移动端 IE等)

移动端建议使用Document.scrollingElement即可,想全端兼容,大而全的写法如下:

//以获取scrolltop以及设置scrolltop为例
    function getScrollTop() {
        return window.pageYOffset
           ||  document.documentElement.scrollTop  
             ||  document.body.scrollTop;
    }

    function setScrollTop(height) {
        document.documentElement.scrollTop = height;
        document.body.scrollTop = height;
        window.pageYOffset = height;
    }