textarea自适应高度需严格三步:先设height为auto,再读scrollheight,最后赋值;ios safari需requestanimationframe补偿延迟,ie11需+2px修正;同步映射必须用input事件并复用三步逻辑;css须设min-height、max-height、overflow-y和box-sizing。

textarea 自适应高度必须先清 height 再读 scrollHeight
直接写 this.style.height = this.scrollHeight + 'px' 会越撑越高,尤其在 iOS Safari 和 IE11 上明显。因为浏览器把上一次设置的 style.height 当作约束——比如上次设了 200px,这次再读 scrollHeight,它就按“不能超 200px”来算,结果偏小。
必须严格三步走:
- 先执行
textarea.style.height = 'auto' - 再读
textarea.scrollHeight - 最后赋值
textarea.style.height = textarea.scrollHeight + 'px'
缺一不可。别用 offsetHeight 或 clientHeight 替代,它们不含溢出内容,永远撑不开。
同步映射时 input 事件比 keyup 更可靠
要让两个 textarea 高度实时一致,监听 input 是唯一稳妥选择。它能捕获粘贴、拖入、剪切、自动补全等所有内容变更,而 keyup 漏掉粘贴和右键粘贴。
同步逻辑不能只复制 value,还得同步高度计算:
- 对主
textarea绑定input,触发后立即重算自身高度 - 同步更新副
textarea.value,再调用同一套三步高度重置逻辑 - 避免用
setTimeout延迟同步,否则快速输入时副框高度滞后、光标错位
注意:若副 textarea 是只读或禁用状态,需加 pointer-events: none 防止误触,但不影响 JS 修改其 value 和 style.height。
iOS Safari 和 IE11 的 scrollHeight 偏差必须单独处理
iOS Safari 对 scrollHeight 更新有微小延迟,尤其在高刷屏或粘贴大段文本后,高度常卡在旧值;IE11 则把 \r\n 当一个字符算,导致空行末尾高度偏小约 2px。
解决方案不是绕开,而是针对性补偿:
- iOS Safari 必须包
requestAnimationFrame:每次input触发后,先textarea.style.height = 'auto',再进requestAnimationFrame里读scrollHeight并赋值 - IE11 检测用
!!window.MSInputMethodContext && !!document.documentMode,高度计算加+ 2补偿 - 若后端不要求保留原始换行符,可统一
textarea.value = textarea.value.replace(/\r\n/g, '\n')再算高
CSS 必须显式控制 min-height、max-height 和 box-sizing
JS 算高度只是半截活。没设 min-height,空 textarea 默认可能只有 20px 高,用户点不中;不限 max-height,粘贴万字文档能把页面顶飞。
这四条 CSS 缺一不可:
-
min-height: 80px(保证初始可点击) -
max-height: 300px(超限时才出滚动条) -
overflow-y: auto(不写会裁切内容) -
box-sizing: border-box(确保padding/border不额外加高)
顺手加上 resize: none 和 overflow: hidden,避免用户拖拽破坏自适应逻辑。这些不是可选项,是防止线上崩溃的底线配置。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











