textarea 的 maxlength 属性无法拦截粘贴、中文输入法未上屏及拖入文本,必须用 oninput 事件监听并手动截断;需配合 compositionstart/end 处理输入法中间态,paste 事件需 settimeout 延迟读值或统一走 oninput;layui 表格中 edit:"textarea" 不支持 maxlength,须用 templet 自定义模板并手动绑定事件。

maxlength 属性单独写在 <textarea></textarea> 上,浏览器会拦截部分超长输入,但对粘贴、中文输入法未上屏内容、拖入文本完全无效——必须用 JavaScript 主动监听和截断。
oninput 事件是唯一可靠入口
只靠 onkeyup 或 onpropertychange 会漏掉粘贴、语音输入、鼠标右键粘贴等操作;oninput 覆盖所有值变更场景,包括 composition 结束、粘贴完成、删除、回车换行。
- 必须在
oninput回调里做长度判断和截断,不能只靠提示或后端校验 - 截断后要手动赋值:
obj.value = obj.value.slice(0, max),否则 DOM 值和实际不一致,光标会跳到末尾 - 避免在截断后再次触发
input(如 Vue/React 的双向绑定),Layui 原生表单无此问题,但自定义封装时需注意
中文输入法必须处理 compositionstart/end
用户用拼音打「中国」时,输入框内先显示「zhongguo」再上屏为「中国」,中间态若被截断,会导致输入中断或乱码。
- 监听
compositionstart时设标志位暂停截断逻辑 - 监听
compositionend后立即执行一次长度检查并截断 - 不要在
compositionstart中直接清空或修改 value,这会干扰输入法状态
粘贴事件要 setTimeout 延迟读取
监听 paste 事件时,event.clipboardData 可读,但 textarea.value 还没更新;直接 obj.value.length 拿到的是旧值。
- 在
paste回调里用setTimeout(() => { /* 检查并截断 */ }, 0) - 或统一走
oninput,它天然在粘贴内容写入后触发,更简洁 - 如果同时监听
paste和input,记得去重:截断后设临时标记,防止input再次触发同一逻辑
Layui 表格中 edit: "textarea" 不支持 maxlength
表格单元格启用编辑模式时,edit: "textarea" 是 Layui 封装的快捷方式,它动态插入 <textarea></textarea> 但不透传 maxlength,也不允许绑定自定义事件。
- 必须改用
templet自定义模板,手写带oninput的<textarea></textarea> - 模板内要确保父容器有
position: relative,否则字数提示.word会定位错乱 - 动态渲染的表格行(如添加新行)需在
layui.table.render()后重新绑定事件,或用事件委托
真正难的不是写几行截断代码,而是把 composition、paste、动态插入、多实例共存这些边界情况全兜住——多数人只测了键盘输入,一上线就被用户粘贴和中文输入法打脸。











