Blazor应用中清空内容后输入时textarea的scrollHeight每次减少2px问题
修复Blazor中textarea自动调整高度的异常问题
核心问题分析
你的autoResize函数出现scrollHeight异常减少的问题,主要由三个原因导致:
- 原生
rows属性与自定义height样式冲突:同时设置rows和手动修改style.height会让浏览器的高度计算逻辑混乱,尤其是清空内容后重新输入时,原生属性残留的计算值会干扰scrollHeight的读取。 - 错误的
maxHeight设置:将maxHeight设为当前contentHeight会把textarea的最大高度锁死在当前内容高度,后续输入时无法正确扩展,导致scrollHeight计算异常。 - 未等待重绘就读取scrollHeight:重置高度为
auto后,浏览器需要时间重绘元素,直接读取scrollHeight可能拿到旧的缓存值。
修复方案
1. 调整CSS基础样式
先确保textarea的盒模型统一,避免后续计算偏差:
textarea { line-height: 24px; width: 600px; box-sizing: border-box; /* 可根据需求添加内边距、边框,不影响高度计算 */ padding: 8px; border: 1px solid #ddd; }
2. 重写autoResize函数
移除干扰逻辑,优化高度计算流程:
export function autoResize(minRows, maxRows) { const textarea = document.getElementById("custom-textarea"); if (!textarea) return; const lineHeight = parseFloat(window.getComputedStyle(textarea).lineHeight); const minHeight = minRows * lineHeight; const maxHeight = maxRows * lineHeight; // 重置高度为auto,让浏览器重新计算内容高度 textarea.style.height = 'auto'; // 强制触发浏览器重排,确保scrollHeight是最新值 void textarea.offsetHeight; const contentHeight = textarea.scrollHeight; // 计算目标高度:不超过最大行高,不低于最小行高 let targetHeight = Math.min(maxHeight, Math.max(minHeight, contentHeight)); // 设置溢出状态和最终高度 textarea.style.overflowY = contentHeight > maxHeight ? 'scroll' : 'hidden'; textarea.style.height = `${targetHeight}px`; textarea.style.minHeight = `${minHeight}px`; textarea.style.maxHeight = `${maxHeight}px`; // 保持滚动到底部(可选,根据需求保留) textarea.scrollTop = textarea.scrollHeight; }
3. 调整HTML结构
移除textarea的rows属性,避免原生属性干扰自定义高度逻辑:
<textarea id="custom-textarea" oninput="autoResize(1, 3)"> type e.g. more than 3 rows and strg + a -> delete and type again </textarea>
修复关键点说明
- 移除rows属性操作:完全通过CSS height控制高度,消除原生属性与自定义样式的计算冲突。
- 强制重排:
void textarea.offsetHeight会触发浏览器立即重绘元素,确保读取的scrollHeight是当前内容的真实高度,避免旧值残留。 - 修正maxHeight逻辑:将maxHeight设为
maxRows * lineHeight,符合你预设的最大行数限制,同时允许内容高度在该范围内正常扩展。
验证效果
执行重现步骤后:
- 清空内容再输入时,scrollHeight会随输入内容正确变化,不会出现每次减少2px的异常。
- 内容超过最大行数时自动显示滚动条,少于最小行数时保持最小高度。
内容的提问来源于stack exchange,提问作者lwlstj
相关产品推荐
相关产品推荐

