textarea自动增高必须用js监听input事件,先设style.height='auto'再读scrollheight赋值;仅用keyup会漏粘贴、输入法等场景;需兼容ios和ie11,并配合min-height、max-height、box-sizing等css控制。

textarea 自动增高不是靠 CSS 的 height: auto,它压根不生效;必须用 JS 监听 input 事件,每次先清空内联高度,再读 scrollHeight 赋值——漏掉“先清空”这步,iOS 和 IE11 就会越撑越高。
为什么 input 事件比 keyup 更可靠
粘贴、拖入文本、中文输入法上屏、右键粘贴、自动填充,这些操作都不会触发 keyup,但全都会触发 input。只绑 keyup 等于默认放弃一半输入场景。
-
input是唯一能覆盖所有内容变更来源的原生事件 - 别用
change:它只在失焦时触发,完全不满足实时响应需求 - 也别用
resize:那只是响应用户手动拖拽边框,和内容无关
scrollHeight 必须配合 style.height = 'auto' 使用
浏览器会把上次设置的 style.height 当作约束条件。比如上次设了 200px,这次再读 scrollHeight,它就按“不能超 200px”来算,结果偏小——删文字不缩、粘贴后留白、回车时光标跳动,都是这原因。
- 每次
input触发时,第一行必须是this.style.height = 'auto' - 紧接着再读
this.scrollHeight,然后赋值this.style.height = this.scrollHeight + 'px' - 用
offsetHeight或clientHeight替代?不行,它们不含溢出区域,永远撑不开
iOS Safari 和 IE11 的兼容性补丁要写进逻辑里
iOS Safari 对 scrollHeight 更新有微小延迟,尤其在 120Hz 屏或软键盘弹出后;IE11 把 \r\n 当一个字符算,导致空行末尾高度少算约 2px。
- iOS:必须用
requestAnimationFrame包一层,setTimeout(..., 0)不够稳 - IE11:检测方式是
!!window.MSInputMethodContext && !!document.documentMode,确认后对高度加+ 2 - 换行符归一化(
value.replace(/\r\n/g, '\n'))只在后端不依赖原始换行时可用
CSS 必须显式声明 min-height、max-height 和 box-sizing
JS 只负责“算高”,但“最小能多矮”“最高能多高”“padding 算不算在 height 里”,全靠 CSS 控制。漏掉任何一条,上线后就会出问题。
-
min-height: 80px:空值时保证有可点击区域,否则用户点不中 -
max-height: 300px:防止粘贴万字文档把布局顶飞 -
overflow-y: auto:不写这句,超限时内容被裁切,不是滚动 -
box-sizing: border-box:确保padding和border不额外增加高度 -
resize: none和overflow: hidden也要加,避免用户拖拽或滚动条干扰 JS 计算
最常被忽略的其实是 CSS 和 JS 的脱节:比如字体加载未完成时读 scrollHeight,或者 :invalid 状态下浏览器插入验证伪元素改变了盒模型——这些都会让高度突然多出 1–2 行空白。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











