PC端上拉加载 scroll 监听还是IntersectionObserve API?

如今阶段,相对于 uniApp、小程序,PC端如要实现上拉等类似功能并不是很灵活,最常见监听window scroll吗?此方法可以实现,但相对也有一定性能弊端、容错率、兼容等问题。

两者利弊

addEventListener scroll

优点:实时性 、特定阶段实现特定效果

缺点:性能问题、滚动灵敏度容错率、滚动处理复杂、触发次数过多

描述:首先监听 scroll 很灵活,可以随时随地在某个节段去做一些相应操作列如:dom切入,切出、过度等效果。但是 scroll 会一直存在,鼠标滚轮只要滑动,这个事件会一直触发,导致性能问题,浏览器之间也会存在灵敏度差异,其次计算到达底部会有容错率。

InterSectionObServe API

优点:性能优化、减少事件触发减少负担、交叉懒加载、简单易用

缺点:较低浏览器兼容问题、多目标复杂性、异步执行导致其余逻辑变故、代码量过多

描述:IntersectionObserver是JavaScript API,内部计算目标元素与视窗或祖先元素的交叉区域,提供高性能、简单接口,触发事件通知状态变化,依赖浏览器底层机制,内部优化减少不必要的计算及事件触发。

实现案列

addEventListener scroll

监听出现滚动条元素来实现。

需注意:确保监听的元素已出现滚动条,如果是浏览器出现并不是元素配合 overflow:auto 内部出现,被监听者也要相应变化,以免错误监听导致无任何效果。

// Vue3.0 + ts 
// 挂载后执行
onMounted(() => {
    // 被监听者
    let view = document.querySelector(".home") as HTMLDivElement;
    view.addEventListener('scroll', () => {
        // 限制滚动到底部时触发事件
        // 此处到达底部计算会出现容错率,自行限制下执行次数,并在相应请求中恢复。
        if(
            (view.scrollHeight - view.scrollTop) <= view.offsetHeight
        ){
            // 业务逻辑
            //request axios ...
        }    
    })
})

IntersectionObServe API

new API 传入目标元素实现到底部,目标元素可以是一个或数组多个元素


// 挂载后执行
onMounted(() => {
    // 目标元素集
    let view = document.getElementsByclassName('XXX') as HTMLDivElement;
    // 底部元素
    let finalDom = view[view.length - 1];
    // 初始化构造函数
    const server = new IntersectionObserver( callback: (entries) 一 
    // isIntersecting 是否已到达目标元素
    if (entries[0].isIntersecting) {
        // request 
        // 取消追踪再进行追踪 此处逻辑自行编写
        server.unobserve(finalDom);
    }
    // 追踪目标元素
    server.observe(finalDom);
})