You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无限滚动节流改造后Loading提示不显示问题排查

无限滚动加载提示不显示问题排查与解决

问题描述

我正在实现一个无限滚动脚本,原代码可正常运行。为优化性能尝试添加节流技术,修改window.onscroll事件逻辑:滚动触底时先设置loading.innerHTML为“Loading...”,await延迟1秒后调用load函数,再清空loading内容。但实际运行时load函数可执行,“Loading...”却完全不显示,控制台无报错。

原代码

HTML

<div id="content"></div>
<div id="loading"></div>

JavaScript

var page = 0,
    proceed = true,
    message;
    
const load = () => {
    if (page < 10 && proceed) {
        proceed = false;
        fetch("", {
                body: "page=" + page,
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded"
                },
                method: "POST"
            })
            .then(res => res.ok ? res.json() : Promise.reject(res))
            .then(res => {
                res.forEach(el => content.innerHTML += ...);
                page++;
                proceed = true;
            });
    }
};

window.onscroll = () => {
    var { scrollTop, scrollHeight, clientHeight } = document.documentElement;
    if (scrollTop + clientHeight >= scrollHeight - 5) load();
};

load();

修改后的滚动事件代码

const delay = time => new Promise(res => setTimeout(res, time));

window.onscroll = () => {
    var { scrollTop, scrollHeight, clientHeight } = document.documentElement;

    if (scrollTop + clientHeight >= scrollHeight - 5) {
        loading.innerHTML = "Loading...";
        await delay(1000);
        load();
        loading.innerHTML = "";
    }
};

问题根源

  1. async关键字缺失:使用await的函数必须声明为async,你修改后的onscroll回调未添加该关键字,导致浏览器无法识别await,会同步执行所有代码——瞬间完成loading.innerHTML的设置与清空,因此看不到加载提示。
  2. 未结合原有节流逻辑:滚动事件会高频触发,即使修复async问题,若不通过proceed变量控制,会多次触发加载流程,导致loading内容被频繁覆盖;同时load函数是异步的,延迟1秒后调用load就立刻清空loading,会导致提示在数据加载完成前就消失。

解决方法

步骤1:给滚动回调添加async关键字

确保await能正常工作,让代码按预期顺序执行。

步骤2:修改load函数返回Promise

让load支持await,确保等待数据加载完成后再清空加载提示。

步骤3:复用proceed变量做节流

避免滚动事件重复触发加载逻辑,同时在加载完成(或出错)后解锁。

修正后的完整代码

调整后的load函数

const load = () => {
    return new Promise((resolve, reject) => {
        if (page < 10) {
            fetch("", {
                    body: "page=" + page,
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded"
                    },
                    method: "POST"
                })
                .then(res => res.ok ? res.json() : Promise.reject(res))
                .then(res => {
                    res.forEach(el => content.innerHTML += ...);
                    page++;
                    resolve();
                })
                .catch(err => {
                    console.error("加载失败:", err);
                    reject(err);
                    proceed = true; // 出错时解锁,允许后续加载
                });
        } else {
            resolve();
        }
    });
};

调整后的滚动事件

const delay = time => new Promise(res => setTimeout(res, time));

window.onscroll = async () => {
    const { scrollTop, scrollHeight, clientHeight } = document.documentElement;

    if (scrollTop + clientHeight >= scrollHeight - 5 && proceed) {
        proceed = false;
        loading.innerHTML = "Loading...";
        await delay(1000); // 可选延迟,若不需要可删除
        try {
            await load();
            loading.innerHTML = "";
        } finally {
            proceed = true; // 无论成功失败都解锁
        }
    }
};

额外说明

  • 若不需要刻意的1秒延迟,可直接删除await delay(1000),避免不必要的等待,提升用户体验。
  • 原代码中的proceed变量是核心节流控制,修改时务必保留,防止滚动事件频繁触发加载请求。

内容的提问来源于stack exchange,提问作者AbsoluteBeginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:06:02