2022年12月05日 天气阴
今天也是日常搬砖的一天,然后将项目推到公共模板上。
效果很不错
结果一起工作的同事就发现了个大问题
下拉加载失效了
问题排查
一 问题梳理
先来个类似的下拉加载代码,如下:
let box = document.body;
window.addEventListener('scroll', () => {
if (loadMoreHeight + box.scrollTop > box.scrollHeight - box.clientHeight) {
loadData()
}
});
loadMoreHeight(自定义触发下拉加载的高度)
scrollHeight(文档内容实际高度)
scrollTop(滚动条距离顶部距离)
clientHeight(窗口可视高度)
四者关系如下所示
这个下拉加载非常简单就是判断(loadMoreHeight + scrollTop + clientHeight > scrollHeight)
二 排查滚动监听
未接公共模板之前是可以正常使用的,所以第一步排查window.addEventListener('scroll', ()=>{}) 是否正常使用
window.addEventListener('scroll', () => {
console.log('触发了scroll')
})
效果如下
所以排除滚动监听
三排查涉及参数
正常下拉加载还涉及到scrollHeight,scrollTop,clientHeight,同上我们输出看看
window.addEventListener('scroll', () => {
console.log(box.scrollHeight, box.clientHeight, box.scrollTop)
})
本地效果如下: (数据正常且支持下拉加载)
但我们部署到线上是有问题的,将代码部署到线上看看效果。
线上效果如下:
显而易见scrollTop,始终为0
四 重点
本地编译的时候用到模板是项目自定义的,而线上的模板是公共模板,二者最大的区别就是html5
查阅资料之后发现:
1.页面指定了DOCTYPE时,需要使用document.documentElement.scrollTop。(而线上滚动加载异常的原因是这个导致的,使用了html5,第一行就是DOCTYPE)
2.页面未指定了DOCTYPE时,需要使用document.body.scrollTop。(因为本地没有指定DOCTYPE所以可以正常取到scrollTop的值)
因此代码改成如下即可
window.addEventListener('scroll', () => {
if (loadMoreHeight + (document.documentElement.scrollTop || document.body.scrollTop) > box.scrollHeight - box.clientHeight) {
loadData()
}
});
总结
假如你的滚动加载用了scrollHeight,scrollTop,clientHeight
1.下拉加载失效时,先看有没有滚动条,一般下拉加载都需要关联滚动条,如果没有滚动条看看是不是数据不够或者加了overflow:hidden
2.如果滚动条都有的话,且滚动条监听正常,就要看看scrollHeight,scrollTop,clientHeight参数是否正常。
(scrollTop始终为0的话,看看是否指定了DOCTYPE,是则要用document.documentElement.scrollTop,否则document.body.scrollTop)
补充: 不同浏览器对于scroll的兼容不同(亲测)
火狐,谷歌:指定了DOCTYPE document.documentElement.scrollTop,未指定document.body.scrollTop
ie:指定了DOCTYPE document.documentElement.scrollTop,未指定 document.body.scrollTop
safari:window.pageYOffset
因此使用时可以兼容下:
document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop