JS实现滚动条触底加载更多

JavaScript012

JS实现滚动条触底加载更多,第1张

原理

1.通过监听滚动区域DOM的scroll事件, 计算出触底

// 滚动可视区域高度 + 当前滚动位置 === 整个滚动高度

scrollDom.clientHeight + scrollDom.scrollTop === scrollDom.scrollHeight

2.触底后触发列表添加, 列表添加使用createDocumentFragment, 将多次插入的DOM先存入内存, 最后一次填充进去, 提高性能, 也方便后面的MutationObserver监听

3.使用MutationObserver监听列表的DOM添加, 添加完毕后, 隐藏加载中提示

示例

https://codepen.io/klren0312/full/dybgayL

参考资料

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/clientHeight

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollHeight

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollTop

https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalEventHandlers/onscroll

https://developer.mozilla.org/zh-CN/docs/Web/API/Document/createDocumentFragment

https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver

背景: js实现滚动条一直在底部靠的是元素的scrollTop和scrollHeight来实现的,可是在React中有些行不通。

原理: 在容器的底部添加一个空的div,使该div一直处于浏览器视口内,这样就可以让容器的滚动条位于底部。

知识点:

useState: 通过在函数组件里调用它来给组件添加一些内部 state, useState 唯一的参数就是初始 state

useEffect: 给函数组件增加了操作副作用的能力,它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。

useRef: 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。

Element.scrollIntoView() : 让当前的元素滚动到浏览器窗口的可视区域内。

方案一:用hooks实现

方案二:用类组件实现

个人推荐第一种方案,第二种方案可行但是操作DOM性能一般。

先上原理图:

判断滚动条是否到临近页面底部,关键是求得上图中 ? 的数值,明显看出这个值 = 文档总高度 - 已滚动部分的高度 - 当前视口高度,所以有如下代码:

var minAwayBtm = 100  // 距离页面底部的最小距离

$(window).scroll(function() {

        var awayBtm = $(document).height() - $(window).scrollTop() - $(window).height()

    console.log('当前距离页面底部:' + awayBtm + 'px')

    if (awayBtm <= minAwayBtm) {

        console.log('触发了')

    }

})