reset() 恢复的是初始 html 的 defaultvalue/defaultchecked,而非清空;动态添加的控件、第三方组件、contenteditable 等需手动清理。

reset() 调用后字段没变?检查 defaultValue / defaultChecked 是否被覆盖
表单重置不是“清空”,而是回退到页面加载时的 defaultValue、defaultChecked、defaultSelected 状态。如果你用 JS 执行过 input.value = "xxx",但没同步更新 input.defaultValue = "xxx",那么 form.reset() 仍会把值设回原始 HTML 的 value 属性(可能是空字符串或旧默认值)。
- textarea 要用
defaultValue,不是innerText或innerHTML - checkbox/radio 改变状态后,记得同步
input.defaultChecked = input.checked - select 需确保初始
<option selected></option>存在,且 JS 修改 selectedIndex 后未破坏该状态 - 动态渲染的控件(如 Vue/React 组件内嵌的 input)通常不参与原生 reset,因其 DOM 不在初始 HTML 中
点击 <input type="reset"> 没反应?先看 DOM 结构和控件有效性
按钮必须是 <form></form> 的**直接子元素**(不能嵌套在 <div> 或 <code><fieldset></fieldset> 内),否则部分浏览器(尤其 IE11 或严格模式下的 Chromium)会忽略它。同时,form 内至少得有一个**启用的、可重置的控件**(input、textarea、select、button),禁用(disabled)或隐藏(display: none)的控件不影响触发,但用户看不到效果,容易误判为“失效”。
- 用浏览器开发者工具高亮检查:按钮父节点是否为
<form></form>? - 确认表单内存在非
disabled的input、select等 —— 空表单或全 disabled 会导致 reset 行为静默 -
<button type="reset"></button>和<input type="reset">行为一致,但前者支持 innerHTML,更易加图标或文案
想在重置前弹窗确认或清理富文本?必须用 event.preventDefault() 拦截 reset 事件
reset 事件在重置**开始前**触发,且可取消;但它只对表单层级有效,不是按钮 click 事件。如果只监听按钮 click,无法阻止默认重置行为,也无法拿到重置前的字段快照。
- 正确写法:
form.addEventListener("reset", (e) => { e.preventDefault(); /* 自定义逻辑 */ editor.setContent(""); form.reset(); }); - 错误做法:给
<input type="reset">绑定onclick并调用confirm()—— 此时重置已发生,拦截无效 - 注意:
reset事件不冒泡出<form></form>,也不触发子元素的input或change事件,如有校验依赖这些事件,需手动 dispatch
动态添加的字段、第三方组件、contenteditable 区域怎么重置?form.reset() 完全不处理它们
原生 reset() 只遍历初始 HTML 中存在的表单控件。JS 动态插入的 <input name="dynamic">、react-select 渲染的下拉、quill 编辑器的 contenteditable 区域,都不会被还原 —— 因为它们没有“初始值”概念。
- 通用清理方案:
document.querySelectorAll('input:not([type=hidden]), textarea, select, [contenteditable]')+ 分类赋值 - 对
contenteditable元素,设el.innerText = ""或el.innerHTML = ""(注意 XSS 风险) - 第三方组件需调用其自身 API,例如
editor.clear()、datepicker.setDate(null) - 隐藏域(
type="hidden")默认不重置,业务需要时要单独处理
重置逻辑越复杂,越容易混淆“恢复初始值”和“彻底清空”——前者靠浏览器原生机制,后者必须手动控制每个字段的最终状态。动态字段、跨框架组件、自定义编辑器,都绕不开显式清理。











