调用 event.preventDefault() 是阻止表单提交最直接的方式;必须绑定在 form 元素的 submit 事件上,而非按钮 click;避免使用 onsubmit="return false" 内联写法;注意 button type 属性需显式声明;fetch 提交时需处理异步状态、错误及按钮禁用/恢复。
event.preventDefault() 是最直接的方式HTML5 本身没有新增专门“阻止提交”的属性或标签,核心还是靠 JavaScript 拦截 submit 事件。只要在表单的 submit 事件监听器中调用 event.preventDefault(),就能阻止浏览器默认的跳转或页面刷新行为。
注意:必须

元素上,而不是按钮的 click;否则可能漏掉回车提交、submit() 方法调用等触发方式。
document.querySelector('form').addEventListener('submit', function (e) {
e.preventDefault();
// 此处写你的自定义逻辑,比如 fetch 提交
});
onsubmit="return false" 也能拦,但不推荐内联写法看似简单,但可维护性差、不利于分离逻辑,且容易和现代框架(如 Vue/React)冲突。更关键的是:它会忽略后续 JavaScript 监听器——一旦写了 return false,其他 addEventListener('submit', ...) 就不会执行。
button 的 type 属性很多问题其实不是事件没拦住,而是按钮本身就在触发提交。如果写成 ,在表单内它默认是 type="submit",点一下就直接提交——哪怕你 JS 已绑好 preventDefault,也可能因执行时机或错误导致拦截失败。
稳妥做法是显式声明类型:
:需要 JS 拦截:完全不触发 submit,适合纯 JS 控制场景type,尤其在动态插入按钮时用 fetch 替代传统提交时,容易忽略异步特性导致表单重复提交或状态错乱。
button.disabled = true 应在 preventDefault 后立刻执行fetch 失败:网络错误、4xx/5xx 响应不会抛异常,需手动检查 response.ok
disabled,否则用户无法重试alert(data.message),应更新对应 DOM 节点复杂表单校验、文件上传、多步骤提交这些场景下,preventDefault 只是起点,真正难点在状态同步与用户体验闭环。