
maxlength 属性不截断已输入内容,只阻止超出长度的字符进入 input.value;它对 type="number"、type="date" 等完全无效,且表单提交时默认不校验该限制。
maxlength 是“拦截”不是“截断”
浏览器在用户按键、粘贴或 IME 上屏瞬间就拒绝超长字符,input.value 始终不会超过设定值。这和后端字符串 substr() 或 JS 手动 slice() 截断有本质区别:
- 用户输入 5 个字符,
maxlength="5"时第 6 次按键(含 Ctrl+V)直接被忽略,不触发input或change事件 - 粘贴整段 20 字符文本时,浏览器自动裁剪为前 5 个再插入,DOM 值始终合规
- 如果你用 JS 动态设
el.maxLength = 3,但当前el.value已是 "12345",这个值不会变——必须手动el.value = el.value.slice(0, 3)
哪些 type 支持 maxlength?哪些不支持?
它只对按字符处理的文本类控件生效,行为差异明显:
- ✅ 有效:
type="text"、type="password"、type="email"、type="tel"、type="url"、type="search"、<textarea></textarea> - ❌ 完全无效:
type="number"、type="date"、type="range"、type="checkbox"、type="file"——写了也不报错,但浏览器直接忽略 - ⚠️ 注意:
type="search"默认maxlength="524288",几乎等同于不限制
为什么表单提交时 maxlength 不报错?
HTML5 表单原生验证(如 form.checkValidity() 或点击 <input type="submit">)默认**不检查** maxlength。它只响应 required、pattern、min/max(对 number/date)等显式验证属性。
立即学习“前端免费学习笔记(深入)”;
- 用户禁用 JS 后手动修改 DOM,把
maxlength="5"的 input 值改成 "123456",表单仍能成功提交 - 想让它参与校验,得用 JS 主动设置
el.setCustomValidity()并监听input事件同步状态 - 更可靠的做法:用
pattern=".{" + min + "," + max + "}"(例如pattern=".{"1,10}"),这样提交时会触发原生提示
移动端和 textarea 的特殊坑
<textarea></textarea> 虽支持 maxlength,但粘贴行为不可靠;移动端 WebView 更容易出问题:
- 用户粘贴超长文本到
<textarea maxlength="100"></textarea>,部分 Android WebView 会完整插入,导致value.length > 100 - 仅监听
input事件还不够:截断el.value = el.value.slice(0, el.maxLength)会重置光标位置 - 如需保留光标,得配合
el.setSelectionRange()手动恢复,或用el.setRangeText()更安全地替换 - 服务端必须二次校验——任何前端长度控制都可被绕过,这是硬性底线



















