最典型的“假死”错觉是点击删除按钮后无反馈但请求已发出;应请求发出即禁用按钮、显示“删除中...”并加loading状态,fetch响应后恢复ui。

点击删除按钮后页面没反应,但网络请求已发出
这是最典型的“假死”错觉——前端没给用户任何反馈,其实 fetch 或 XMLHttpRequest 已发出去,后端也正在处理。用户反复点、刷新、怀疑功能坏了。
解决的关键不是等后端返回再提示,而是「请求发出即反馈」:
- 点击瞬间禁用按钮,文字改为
"删除中...",加disabled属性防重复提交 - 用 CSS 给按钮加 loading 状态(比如旋转图标),别只靠文字
- 如果用
fetch,.then()前就该恢复按钮状态;别等到.catch()才动
示例:
button.addEventListener('click', () => {
button.disabled = true;
button.textContent = '删除中...';
fetch('/api/item/123', { method: 'DELETE' })
.then(() => {
button.disabled = false;
button.textContent = '已删除';
// 后续 UI 清理
})
.catch(() => {
button.disabled = false;
button.textContent = '重试';
});
});
后端删得慢,前端怎么显示真实进度
HTTP DELETE 本身不支持流式进度,所谓“真实进度”只有两种可靠来源:轮询状态接口 或 Server-Sent Events(SSE)。WebSocket 过重,不推荐只为删数据上。
常见错误是把“请求发送时间”当进度起点,结果用户看到 0% → 100% 一闪而过,毫无意义。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 后端需提供独立的状态查询接口,如
/api/task/abc123/status,返回{ progress: 65, status: "processing" } - 前端发起删除后,立刻启动
setInterval轮询(建议间隔 1–2s,超时设 30s) - 一旦返回
status: "completed"或"failed",立即清除定时器并更新 UI - 别用
setTimeout递归模拟轮询——容易堆栈溢出或失控
用 form 提交 DELETE 请求时状态无法控制
原生 <form method="DELETE"></form> 不合法(HTML 规范只认 GET/POST),实际会被降级为 GET,导致误删或 405 错误。
更麻烦的是:表单提交会整页跳转或刷新,根本没法做按钮禁用、进度条这些交互。
- 必须用 JavaScript 拦截表单提交,调
fetch或axios发送 DELETE - 在
event.preventDefault()后立刻操作 UI,别等异步完成 - 如果服务端不支持 DELETE,改用 POST +
_method=DELETE(Laravel 风格),但前端仍要手动发请求,不能依赖表单原生行为
移动端点击删除后键盘没收起,遮挡进度提示
iOS Safari 和部分安卓浏览器里,如果删除按钮在输入框下方,点击后软键盘常不自动收起,导致进度文字被挡住,用户以为卡住。
- 删除前主动触发
document.activeElement?.blur(),让焦点离开输入框 - 不要依赖
focusout或blur事件来判断——它们可能不触发或延迟 - 如果页面有多个输入框,且你不确定哪个有焦点,直接遍历
document.querySelectorAll('input, textarea')并调blur()
这个细节没人提,但线上投诉最多的就是“点了没反应”,其实是键盘盖住了 "删除中..." 四个字。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










