列表无限滚动加载——web实现(监听Scroll滚动距离)

一、实现过程

在用户浏览网页时,滑动条滚动到底部时加载新数据是常见的业务,会给用户带来良好的体验。

而实现无限滚动加载的方式有很多,可以通过第三方web组件库的相关api来实现,也可以通过原生js监听滚动距离来实现。

这里介绍第二种原生的实现方式,普适性更好。

  • const scrollTop = window.pageYOffset || document.documentElement.scrollTop;

    • window.pageYOffset 返回当前窗口相对于初始包含块的垂直偏移量,即滚动条从顶部向下滚动了多少像素。
    • 若 window.pageYOffset 不可用(例如在一些较旧的浏览器中)时,则使用 document.documentElement.scrollTop。document.documentElement.scrollTop 表示<html> 元素的滚动偏移量,同样是页面垂直方向上的滚动距离。
  • const vHeight = window.innerHeight || document.documentElement.clientHeight;

    • window.innerHeight 返回浏览器窗口的内部高度,即视口的高度,不包括浏览器的地址栏、工具栏等。
    • document.documentElement.clientHeight 是 <html> 元素的客户区高度,通常情况下与视口高度相同。
  • const pageHeight = document.documentElement.scrollHeight;

    • document.documentElement.scrollHeight 表示 <html>  元素的完整高度,即整个页面内容的高度,包括需要滚动才能看见的部分。

当 滚动距离+视口高度 >= 页面内容高度 时,即滚动到底了。

在实际代码中可以把页面内容高度适度减去一定的像素,留出加载数据的提前量,避免用户滚动到底部时等待加载数据。

在滚动到底部时还有一个问题,那就是触发事件太过频繁,显然这是不行的。

这时就需要节流或者防抖了。这里选择节流的方式,通过节流,可以限制滚动事件触发请求的频率,确保在用户滚动过程中较为平滑地加载新内容,避免过于频繁地发送请求对服务器造成不必要的压力,同时也提升了用户体验。

封装一个节流函数throttle,传入事件执行函数和时间间隔即可。

二、最终代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <div style="height: 3000px;width: 100%;background: gray;"></div>
</body>



<script>
    const throttle = (fun, delay) => {
        let last = 0;
        let timer = null;
        return function throttled(...args) {
            const now = Date.now();
            if (now - last >= delay) {
                clearTimeout(timer); // 清除之前可能存在的定时器
                fun.apply(this, args);
                last = now;
            } else if (!timer) { // 如果在delay时间内再次触发,重新设置定时器
                timer = setTimeout(() => {
                    fun.apply(this, args);
                    timer = null;
                }, delay - (now - last));
            }
        };
    };


    const handleScroll = function () {
        const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
        const vHeight = window.innerHeight || document.documentElement.clientHeight;
        const pageHeight = document.documentElement.scrollHeight;
        if (vHeight + scrollTop >= pageHeight - 500) { 
            //-500是为了在滚动到底部前提前获取数据,提高用户体验
            console.log("到底了, 发请求获取数据");
        }
    };


    window.addEventListener('scroll', throttle(handleScroll, 500));
</script>

</html>

  • 25
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
参数说明 listLoadingMore({id:"",id2:function(){},action:function(){},pageNum:10,getNew:undefined,funcArg:undefined,func:function(){},loadingMustTime:0,loadingDom:function(){},loadedDom:function(){},nullDataFunc:function(){},endFunc:function(){},errorFunc:function(){}}); id:滚动条id,不可以是body; id2:滚动列表的id,通过function自行根据情况返回; action:数据来源的ajax地址,插件会自动加上page和length(分别表示请求页数和当前已有记录数),返回格式统一是[{},{}...],此类jsonArray; ajaxType:ajax提交方式,将更改传递数据的方式,默认post; pageNum:每页加载数量,将会根据这个数量判断是否全部加载完成; getNew:自定义获取数据方法; funcArg:自定义获取数据时传递的参数,类型为函数,返回所需参数; childrenTag:列表子项的标签,默认LI; func:非自定义获取数据时,创建每行数据的方法; loadingMustTime:强制最小加载时间,默认0; loadingDom:加载中动画自定义,返回Dom或者HTML代码; loadedDom:完全加载完成动画自定义,返回Dom或者HTML代码; nullDataFunc:数据列表为空时执行的方法; endFunc:每页数据加载完成时执行的方法; errorFunc:ajax获取数据失败时调用的方法。 回调方法 调用本方法初始化后将会得到一个专属的方法集: Object {getNew:function,isFull:function,isRunning:function,isStop:function,loading:function,show:function}; getNew():忽略判断条件,强制执行加载操作。此时数据传递中,page值可能出错,但length值一定正确,请谨慎判断后在执行该方法; isFull(boolean):修改列表加载完成标志。true为全部加载完成,false则相反; isRunning(boolean):修改列表当前是否正在加载中标志。几乎没有使用的机会; isStop(boolean):设置是否停止加载,设置为true时将会阻止未来的所有加载操作; loading():根据当前滚动条的位置,自动判断是否需要加载新数据; show(boolean,boolean):强制设置加载中和加载完成dom的显示或隐藏,true表示显示,false相对。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值