maxlength能限制textarea字符数,但按UTF-16码元计(非用户感知字数),仅拦截键盘输入;粘贴、拖入、语音输入、JS赋值及初始超长值均绕过该限制,须配合input/paste事件监听、手动截断及后端一致校验。

maxlength 能限制 textarea 的字符数,但不是“字数”——它按 JavaScript 的 string.length 计,即 UTF-16 码元数,中文、英文、换行符都算 1,但 ?? 这类组合 emoji 可能占 2–4。
为什么设置了 maxlength 还能粘贴超长内容?
原生 maxlength 只拦截键盘按键,对以下操作完全无效:
- 右键粘贴(
paste事件) - 拖拽文本入框
- 语音输入完成上屏后
- JavaScript 直接赋值:
textarea.value = longString
浏览器不会自动截断已有超长内容,也不会校验初始化时的默认值。若服务端返回了 300 字的初始值,而 maxlength="200",用户仍可看到并提交全部 300 字。
如何让 maxlength 真正兜住输入?
必须搭配 JavaScript 实时监听和截断,且优先用 input 事件(不是 keydown 或 change):
立即学习“前端免费学习笔记(深入)”;
- 监听
input和paste两个事件,paste中调用event.preventDefault()再手动处理 - 截断用
el.value = el.value.slice(0, limit),避免正则误删代理对 - 初始化时主动清理:
textarea.value = textarea.value.slice(0, 200) - 富文本编辑器(如 Quill、Tiptap)中,
maxlength无效,须改用其内置 API 控制
移动端和旧浏览器要注意什么?
iOS Safari 对 maxlength 支持稳定,但部分安卓输入法(Gboard、搜狗)在 IME 组词阶段会临时超出限制,光标还能移动,直到上屏才触发截断。旧版 Safari(iOS 9–10)和某些 Android WebView 会直接忽略 maxlength 属性。
安全底线始终是:前端所有限制都可绕过,textarea.value.length 校验必须在后端重做,且逻辑需与前端一致(比如都按 UTF-16 码元计,而非字节或“视觉字数”)。



















