根本原因是按钮在表单内未设type属性时默认为submit,触发表单提交导致页面刷新;应显式设置type="button"或调用event.preventDefault()阻止默认行为。

点击按钮后页面不刷新,根本原因不是按钮本身,而是它触发了默认行为——比如在 <form></form> 里没设 type 的 <button></button> 会自动提交表单,导致整页 reload。
为什么
浏览器对 <button></button> 的默认 type 是 submit,不是“没行为”。只要它在 <form></form> 标签内,且没显式写 type="button",点击就会触发表单提交,哪怕后端接口根本没配、甚至没写 action 属性。
- 错误写法:
<form><button>加入购物车</button></form>→ 刷新 - 安全写法:
<button type="button" data-product-id="1057">加入购物车</button>→ 不刷新 - 如果真要用表单(比如带数量输入框),必须加
event.preventDefault(),否则 fetch 再快也拦不住 submit
用fetch发请求但页面还是闪了一下
不是 fetch 的问题,是按钮或父元素绑了其他副作用:比如 <a href="#"></a> 包着按钮、或者 JS 里写了 location.reload()、又或者 CSS 里用了 scroll-behavior: smooth 配合锚点跳转,都会造成视觉“闪”。
- 禁用所有
href="#"或href="javascript:void(0)",改用<button type="button"></button> - 检查 JS 是否有无意调用
window.location或history.pushState()后又回退 - 避免在点击处理函数末尾写
return false(旧式 jQuery 写法),现代原生事件用event.preventDefault()更精准
如何确认刷新到底是谁干的
打开浏览器 DevTools → Network 标签页,点按钮,看第一个请求是不是 document 类型(即 HTML 页面请求)。如果是,说明有表单 submit 或链接跳转;如果只有 fetch 发出的 cart/add 请求,但页面仍刷新,那大概率是 JS 主动调了 location.reload() 或路由跳转。
立即学习“前端免费学习笔记(深入)”;
- 在按钮点击 handler 开头加
console.trace('add-to-cart clicked'),看调用栈里有没有意外的 reload - 临时注释掉所有
location.相关代码再试 - 检查是否误把按钮放在了
<form onsubmit="submitForm()"></form>里,而submitForm()末尾忘了event.preventDefault()
最常被忽略的一点:很多人以为“不刷新”只靠阻止 submit 就够了,其实还要确保没有其他 DOM 操作触发重排/重绘抖动,比如在更新购物车徽标时直接 innerHTML 整段替换节点,会导致列表闪烁——应该用 textContent 更新数字、用 classList.toggle() 控制状态,保持 DOM 稳定。



















