因为maxlength仅拦截键盘输入,对粘贴、拖拽、ime组词等无效;需监听input事件手动截断并配合setselectionrange保持光标,且服务端必须二次校验。

maxlength="10" 为什么粘贴 20 个字还能成功?
因为 maxlength 不是拦截器,只是 UI 层的输入截断开关:它只对键盘逐字符输入生效,对 Ctrl+V 粘贴、拖拽插入、移动端输入法“组词未确认”阶段的临时内容完全无效。粘贴后 input 事件照常触发,此时 el.value.length 已远超 el.maxLength。
常见错误现象:<textarea maxlength="100"></textarea> 用户粘贴 150 字 → 表单无提示、能提交、后端收到超长数据。
- 必须监听
input事件(不是keydown),并在回调里手动截断:el.value = el.value.slice(0, el.maxLength) - 若需保留光标位置,得配合
el.setSelectionRange()或更安全的el.setRangeText() - Android WebView(尤其 4.4 以前)对
textarea的maxlength支持极差,JS 容错不可省
minlength="6" 和 maxlength="6" 真的等于“必须输 6 个字”吗?
不等于——除非加 required。因为 minlength 只在值非空时校验;空值触发的是 valueMissing(由 required 控制),不是 tooShort。
实际行为对比:
-
<input type="text" minlength="6" maxlength="6">→ 允许空提交,也允许输 1~5 字(提交时报tooShort) -
<input type="text" minlength="6" maxlength="6" required>→ 空值报valueMissing,1~5 字报tooShort,仅 6 字通过
服务端仍需校验:前端所有限制都可被 DevTools 或 curl 绕过,required 和 minlength 不改变 HTTP 请求体内容。
type="number" 写了 maxlength="3" 为啥没用?
maxlength 和 minlength 仅对文本类控件有效:type="text"、type="password"、type="email"、type="tel"、type="url"、type="search" 和 <textarea></textarea>。以下类型**完全忽略**该属性:
-
type="number":用户可输入任意位数,甚至粘贴 "1234567890" —— 应改用min/max+ JS 校验(如parseInt(el.value) > 999) -
type="date"、type="range"、type="checkbox"、type="file":写了也白写,控制台零提示 -
type="search"默认maxlength="524288",几乎等同于不限制
若坚持用文本框模拟数字输入,可设 type="text" inputmode="numeric" pattern="[0-9]*",再配 maxlength。
表单提交时 maxlength 为啥不报错?
浏览器默认不把 maxlength 当作验证项:调用 form.checkValidity() 或点提交按钮时,它只响应 required、pattern、min/max(对 number/date)等显式验证属性。即使 el.value.length > el.maxLength,表单照样提交成功。
想让它参与原生校验,必须用 JS 主动干预:
- 在
input事件中同步调用el.setCustomValidity(value.length > el.maxLength ? "超出最大长度" : "") - 或更省事:用
pattern=".{" + min + "," + max + "}"(如pattern=".{"1,10}"),这样浏览器会原生弹提示 - 注意:
maxlength不会自动修正已有超长值 —— 动态设置el.value = "123456"后,el.maxLength = 5不会删掉第 6 位,必须手动el.value = el.value.slice(0, 5)
emoji 混输时按 UTF-16 计数(如 "??" 算 2),.length 不等于视觉字符数,前端限制不可靠,服务端最终校验不可跳过。











