需用 maxlength 限制字数并监听 input 事件实时计算剩余字数,因 input 事件覆盖所有输入场景;textarea 与 input 处理一致;超长时避免直接截断以防光标跳失。

用 maxlength 和事件监听实时计算剩余字数
HTML 原生 input 或 textarea 不自带“剩余字数”显示功能,必须靠 JS 监听输入并手动更新。核心是:用 maxlength 限制上限,再用 input 事件(不是 change)捕获每次键入/粘贴/删除动作,实时算出 maxlength - value.length。
注意:input 事件能覆盖键盘输入、剪贴板粘贴、拖拽文本、IM 输入法上屏等所有文本变更场景;而 keydown 捕不到粘贴,change 只在失焦时触发,都不适用。
-
maxlength必须设在 HTML 中或 JS 里同步设置,否则无法作为上限依据 - 中文、Emoji、全角字符在 JS 中都按单个
length计,和浏览器渲染一致,无需额外处理 Unicode 问题 - 若需兼容 IE9+,可用
onpropertychange作降级,但现代项目基本可忽略
textarea 和 input[type="text"] 处理方式完全一致
两者都支持 maxlength 属性和 input 事件,DOM 操作逻辑无区别。不需要为 textarea 单独写适配代码。
常见误区是以为 textarea 要监听 keyup 防止换行符漏算——其实 input 事件天然包含换行符变更,value.length 已准确反映含 \n 的总字符数。
- 示例 HTML:
<textarea maxlength="100" id="desc"></textarea><div id="counter">剩余 100 字</div> - JS 中只需绑定一次:
document.getElementById('desc').addEventListener('input', updateCounter) - 函数内直接用
el.value.length和parseInt(el.getAttribute('maxlength'))计算即可
超出 maxlength 后手动截断会导致光标跳到末尾
如果在 input 事件里检测超长后执行 el.value = el.value.slice(0, max),会强制重置输入框内容,浏览器将光标重置到末尾,破坏用户体验。这不是 bug,而是 DOM 值重赋的必然行为。
更稳妥的做法是:不主动截断,仅做视觉提示(如变红、禁用提交按钮),把截断逻辑交给表单提交前校验。若必须实时截断,需配合 setSelectionRange 保持光标位置:
if (el.value.length > max) {
const pos = el.selectionStart;
el.value = el.value.slice(0, max);
el.setSelectionRange(pos <h3>移动端软键盘唤起时容易丢失 input 事件</h3><p>部分 Android WebView(尤其旧版)在软键盘收起瞬间可能丢掉最后一次 <code>input</code> 事件,导致剩余字数显示滞后。这不是代码问题,而是底层事件调度缺陷。</p><p>缓解方法是在 <code>blur</code> 事件中补一次更新,且仅当值确实变化时才触发:</p>
- 缓存上一次
value.length,在blur里对比,不同则再调一次计数函数 - 不要在
focus或resize上加逻辑,无实际作用 - iOS Safari 通常无此问题,可不处理
真正难搞的是微信内置浏览器某些版本对 input 事件的节流策略,遇到时只能加 setTimeout(..., 0) 微调时机,但别滥用,多数情况原生事件已足够可靠。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











