管用,但仅对新增键盘输入硬拦截,按utf-16码元计数;对粘贴、拖入、中文输入法未上屏、初始值超限、富文本包裹等情况完全失效,服务端必须二次校验。

textarea 的 maxlength 属性到底管不管用?
管用,但只在「新增输入」层面硬拦截,且统计的是 JavaScript 的 string.length(UTF-16 code units),不是视觉字数或字节数。它能挡住键盘连续输入,但对以下情况完全失效:
• 用户粘贴超长文本
• 拖拽文件内容进文本域
• 中文输入法未上屏的候选词阶段
• 服务端返回的初始值已超限(maxlength 不会自动截断已有内容)
• 富文本编辑器包裹的 textarea(实际 DOM 输入不走原生路径)
为什么加了 maxlength 还能输超?常见原因和修复
不是属性写错了,而是它根本没被触发或被绕过了:
• 初始值超限:页面加载后立即执行 textarea.value = textarea.value.slice(0, 200)
• 动态赋值绕过:JS 修改 textarea.value 后没做长度检查,必须手动补截断
• 富文本组件:别碰原生 maxlength,改用 Quill/TinyMCE 的 maxLength 配置项或插件
• DevTools 删除属性:前端限制纯属“礼貌提示”,服务端必须校验 req.body.content.length
input 事件监听比 keydown 更可靠,但要注意 composition
只监听 keydown 会漏掉粘贴、拖入、语音输入;input 覆盖全部变更,但中文输入法下有 compositionstart/compositionend 两阶段:
• 不要在 compositionstart 里截断 value,会破坏输入法状态
• 在 compositionend 后立刻调用一次校验函数
• input 监听保持不变,作为兜底
• 移动端 WebView(如微信)可能不触发 composition 事件,此时只能依赖 input + 延迟校验(setTimeout 0)
显示剩余字数时容易忽略的细节
用户看到“还剩 -3 字”或者光标卡住,往往是因为:
• 没用 Math.max(0, maxLength - value.length),导致负数显示
• 截断后没同步更新计数器,造成 UI 和真实值不同步
• 换行符算 1 或 2 字(\n vs \r\n),但 maxlength 和 JS .length 本就按此计算,无需额外处理
• iOS Safari 粘贴后可能短暂显示超限,等输入法确认上屏才真正截断,这是浏览器行为,无法消除,只能接受
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











