maxlength 对 type="number" 无效,因 HTML5 规范仅支持 text、email、tel、url、password 和 textarea;type="number" 等类型直接忽略该属性,须用 JS 截断并处理 composition、代理对及前后端单位统一。

maxlength 对 type="number" 根本不生效
这是最常被忽略的规范限制:HTML5 明确规定 maxlength 只对 type="text"、type="email"、type="tel"、type="url"、type="password" 和 textarea 有效;type="number"、type="date"、type="hidden" 等类型会直接忽略该属性。
现象就是:<input type="number" maxlength="11"> 写了也白写,用户能输几十位数字,控制台无报错,浏览器也不拦。
- 别试图用 CSS 或样式掩盖这个问题——它不是渲染问题,是规范级失效
- 改用
type="tel"虽能激活maxlength,但语义错误,iOS 键盘仍弹出数字键盘,安卓可能弹出全键盘 - 真正可行的解法只有 JS 截断:
oninput="value = value.slice(0, 11)"或监听input事件手动裁剪
textarea 初始值超限,maxlength 不会自动清理
maxlength 只约束“新增输入”,对已有内容完全不管。服务端返回的 HTML 带着 <textarea>超长文本</textarea>,哪怕写了 maxlength="200",页面一加载就显示 205 字——浏览器不会帮你 slice。
- 初始化时必须主动截断:
textarea.value = textarea.value.slice(0, 200) - 若用 Vue/React,不能直接操作 DOM 的
value,得先处理绑定数据再更新视图,否则响应式脱节 - 富文本编辑器(如 Quill、Tiptap)更麻烦:真实输入在隐藏 DOM 中,原生
maxlength彻底失效,必须调用组件自己的 API(如editor.getLength())
中文输入法未上屏,length 统计滞后
用户打拼音“zhongguo”时,textarea.value 还是空的;按空格确认后,“中国”才上屏,value.length 突然从 0 变成 2——这中间的几十个拼音字母没被算进长度,也没触发截断,但用户已感知到“快超了”。
立即学习“前端免费学习笔记(深入)”;
-
input事件在输入法组合期间不触发,只靠它会漏掉整个组词过程 - 必须同时监听
compositionstart和compositionend:前者暂停校验,后者立即检查并截断 - 移动端尤其危险:Gboard、搜狗等安卓输入法允许组词阶段临时超限,直到上屏才触发
input,此时用户已看到“205/200”却还能编辑
emoji 和换行符让 length 计数失真
maxlength 按 JavaScript 的 string.length(UTF-16 code units)计数,不是人眼看到的“字数”。一个 ?? 算 4 个单位,Windows 换行符 \r\n 算 2 个,某些生僻汉字占 2 个代理对——结果就是:用户明明只输了 198 个“字”,提交却失败。
- 前端实时统计要用
Array.from(value).length,不是value.length - 截断也得用
Array.from(value).slice(0, max).join(''),否则直接slice可能切开代理对,导致乱码 - 后端必须用同样逻辑校验:Python 用
len(list(graphemes)),Node.js 用Array.from(str).length,Java 用str.codePointCount(),不能只用str.length() - 数据库字段宽度(如 MySQL
VARCHAR(200))按字节算,utf8mb4 下 emoji 占 4 字节,200 字符可能撑爆 200 字节字段
slice,而是 composition 状态同步、代理对安全截断、前后端单位对齐这三件事——漏掉任意一个,就会在某个安卓机型、某次粘贴、某个 emoji 出现时突然崩掉。



















