后端至少需返回items、has_more、next_offset三个字段:items为本次插入的结构化数组,has_more为布尔值控制按钮显隐,next_offset提供下一次请求参数,严禁返回HTML字符串以防XSS与DOM重绘。

点击加载更多不是加个按钮再绑个 click 就完事的,核心在于「请求不乱、插入不崩、状态不糊」。只要后端返回结构化 JSON,前端用 insertAdjacentHTML 插入、配合按钮禁用和 loading 状态,90% 的问题就消了。
后端接口必须返回哪些字段?
别让前端猜分页边界。后端至少得提供三个明确字段:
-
items:本次要插入的数组,每项结构必须和首屏一致(比如都有id、title、content) -
has_more:布尔值,决定“加载更多”按钮是否继续显示;不能只看items.length === 0,那会把接口报错空响应当成“已到底” -
next_offset或next_cursor:下一次请求用的参数;别让前端自己算offset + 10,否则跳页、重复拉取、ID 乱序全来了
绝对不要返回 html 字段或带标签的字符串——这是 XSS 风险口,也破坏语义和 SEO。
前端怎么安全追加新内容?
用 innerHTML += 是最常见也最危险的做法:它会让浏览器重新解析整个容器,已绑定的事件、输入框焦点、滚动位置全丢,列表还会闪一下。
正确姿势是只把新内容塞到末尾,不动已有 DOM:
- 如果后端返回 HTML 字符串,用
container.insertAdjacentHTML('beforeend', htmlString) - 如果返回纯 JSON,推荐用
items.map()拼字符串,或document.createElement构建节点再append - 确保容器有明确
id或class,别用模糊选择器如document.querySelector('button')找错父容器
按钮点不动 / 连点崩溃?先查这三件事
90% 的交互失效都卡在这几个地方:
- 按钮是
但没写type="button",又恰巧在里——点击直接触发表单提交。要么加type="button",要么在事件回调里写event.preventDefault() - 没做防连点:点击后不立刻设
button.disabled = true,用户手快点两次,两个请求并发,后返回的覆盖先返回的,列表顺序错乱 - 没加 loading 状态:按钮点击后没加
is-loading类,用户看不到反馈,以为卡死,又猛点。建议 CSS 配合显示“加载中…”或骨架图
fetch 请求乱序覆盖怎么办?
用户快速点两次,“第二次请求先回来”,把第一次的数据冲掉,结果列表重复或错位。这不是 UI 问题,是请求生命周期没管住:
- 最简方案:每次发新请求前,调
abortController.abort()(需在fetch里传signal) - 更稳妥做法:给每次请求打唯一
requestId = Date.now(),全局存一个latestRequestId;成功回调里先比对if (requestId !== latestRequestId) return - 基础兜底:按钮 disabled + loading 状态控制 UI,比纯 JS 标志位更可靠
真正难的不是写加载逻辑,而是让“加载中”“加载失败”“已到底”这三种状态,在网络抖动、后端异常、用户乱点时,始终准确反映真实数据边界。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











