maxlength属性在现代浏览器中可靠,但仅限输入拦截;需JS实时提示、处理粘贴及光标定位,并必须服务端二次校验。
直接用 maxlength 属性,现代浏览器全支持;但必须搭配 JS 做实时提示和粘贴兜底,服务端还得再校验一遍。
maxlength 属性到底靠不靠谱靠谱,但有边界。HTML5 明确规定 maxlength 可用于 <textarea>,按 Unicode 码点计数(也就是 JavaScript 中 value.length 的结果),对中文、英文、emoji 都基本准确。
max-length 拼错,或加在了 <div> 这类非表单元素上maxlength 还不够因为用户需要反馈,而 maxlength 是静默的。它拦得住输入,但不告诉你“还剩几个字”,也不拦得住粘贴、拖入、语音输入等绕过行为。
input 事件是唯一可靠方式:覆盖键盘、粘贴、剪切、拖放、语音输入全部路径keydown 或 keyup:右键粘贴、拖文本、iOS 语音输入都捕获不到compositionstart/compositionend:未上屏的候选词不算数,提前截断会导致输入法异常input,超限时 el.value = el.value.slice(0, MAX),再用 setSelectionRange 锁定光标位置,避免跳到末尾直接赋值 el.value = ... 会导致光标跑到最后,用户在中间插入内容后被截断,体验极差。
立即学习“前端免费学习笔记(深入)”;
el.selectionStart 和 el.selectionEnd
el.setSelectionRange(pos, pos),把光标“钉”回原位setSelectionRange 支持不稳定,可降级为仅提示不拦截(比如只更新字数文案,不改 value)selectionStart === selectionEnd 不成立,需保留选区范围前端限制纯属体验优化。用户禁用 JS、手动删掉 maxlength 属性、用 curl 直接 POST,都能绕过所有前端逻辑。
str.length,不是字节长度)utf8mb4 下 emoji 占 4 字节,但仍是 1 个字符真正麻烦的从来不是怎么写那几行 JS,而是中文输入法异步上屏、iOS 光标重置、服务端字符计数口径统一这三件事——漏掉任何一个,上线后都会收到用户“字数不对”的反馈。