textarea自动撑高需监听input事件,先设height='auto'再赋scrollHeight;移动端Safari需用requestAnimationFrame规避延迟;删除时高度才可收缩,避免滚动条出现。

怎么让 <textarea> 自动撑高不滚动
默认的 <textarea> 输入多行后会出滚动条,但聊天框需要内容增长时高度自动扩展。核心不是用 resize: none 禁掉拖拽,而是监听 input 事件,动态重设 scrollHeight:
- 必须先清空
height(设为auto),再读取scrollHeight,否则读到的是旧值 - 设完高度后要再设回
height(不能只靠min-height),否则删除文字时高度不会收缩 - 移动端 Safari 对
scrollHeight响应有延迟,建议加requestAnimationFrame包一层
textarea.addEventListener('input', () => {
textarea.style.height = 'auto';
textarea.style.height = textarea.scrollHeight + 'px';
});
发送按钮怎么绑定回车和点击双触发
用户既要点按钮,也习惯按 Enter 发送,但直接监听 keydown 容易误触(比如换行)。关键在区分 Shift+Enter 和纯 Enter:
-
event.key === 'Enter' && !event.shiftKey才触发发送,否则调用event.preventDefault()并插入换行 - 按钮点击和回车逻辑应复用同一函数,避免状态不同步(比如发送后没清空输入框)
- 别用
form包裹——它默认会提交刷新页面,除非显式event.preventDefault()
怎么防止用户粘贴富文本或带样式的文字
聊天框里出现 <span style="color:red"> 这类 HTML 或乱码格式,会导致渲染异常或 XSS 风险。不能只靠 textContent 取值,得在粘贴时就拦截:
- 监听
paste事件,调用event.preventDefault() - 用
event.clipboardData.getData('text/plain')拿纯文本,再insertAdjacentText('beforeend', ...)插入光标位置 - 如果需支持 emoji 或链接自动识别,应在纯文本基础上做后处理,而非放行 HTML
为什么用 <div contenteditable> 而不是 <textarea>
当需要内嵌图片、@成员、实时语法高亮等能力时,<textarea> 就不够用了。但 contenteditable 是个深坑:
立即学习“前端免费学习笔记(深入)”;
- 默认会把连续空格/换行转成单空格,需加
white-space: pre-wrap和word-break: break-word - 光标定位复杂:插入内容后需手动恢复 selection,尤其在异步操作(如 @ 提示列表)后容易丢失焦点
- 移动端兼容性差,iOS 上经常无法唤起键盘或光标错位,上线前务必真机测 iOS + Android 各主流浏览器
多数场景下,先用 <textarea> 实现基础功能,等明确需要富交互时再切到 contenteditable —— 这个切换成本比预想中高得多。



















