表单重置后number输入框onchange事件失效问题咨询
数字输入框onchange事件异常问题分析
问题代码
<body> <form id="form_test"> <label>Your name: </label> <input type="text" name="name"> <label>Your age: </label> <input type="number" name="age" onchange="update()" value="0" min="0"> <button type="button" onclick="send(this.form)">Send</button> </form> <script> function send(forma){ let data = Object.fromEntries((new FormData(forma)).entries()); console.log(data); forma.reset(); } function update(){ console.log('Input number has changed'); } </script> </body>
问题现象
提交表单时如果年龄不为1,后续修改年龄(手动输入或用增减按钮)都能正常触发onchange事件的控制台日志;但如果提交时年龄为1,之后用数字输入框的增减按钮修改年龄,onchange事件就会失效,只有手动输入值时才正常。
原因解析
这是浏览器表单重置的类型匹配问题导致的:
form.reset()会将输入框恢复到HTML定义的初始值0,此时输入框的value是数字类型。- 当你提交年龄为1时,FormData获取到的
age值是字符串类型的"1",浏览器会把这个值记录为输入框的"历史有效值"。 - 后续用增减按钮从0(数字)改成1(数字)时,浏览器会拿当前的数字1和之前记录的字符串"1"做对比,类型转换后两者被判定为相等,因此不会触发
onchange事件;而手动输入时,输入内容会被转为字符串,从数字0变成字符串"1",类型和值都发生了变化,所以能正常触发事件。
修复方案
方案1:统一重置后的value类型
在调用reset()后,手动将输入框的value设置为字符串类型的初始值,消除类型差异:
function send(forma){ let data = Object.fromEntries((new FormData(forma)).entries()); console.log(data); forma.reset(); // 手动设置为字符串类型的初始值,确保和FormData获取的类型一致 forma.age.value = "0"; }
方案2:改用input事件
input事件会在输入框值发生任何变化时触发,不受类型匹配问题影响,直接替换onchange为oninput即可:
<input type="number" name="age" oninput="update()" value="0" min="0">
内容的提问来源于stack exchange,提问作者unknown27
相关产品推荐
相关产品推荐

