移动端响应式高度textarea输入时滚动跳顶问题原因咨询
问题分析与解决方案
为什么仅移动端出现滚动跳顶?
移动端浏览器的滚动行为、视口处理逻辑和桌面端存在差异:
- 软键盘弹出会压缩视口高度,浏览器会自动调整页面滚动以保证输入框可见;
- 你当前的逻辑是先将textarea高度设为
auto,再重置为scrollHeight,这种尺寸突变会触发浏览器重排,移动端浏览器在重排过程中容易丢失原有滚动位置,导致滚动条跳至顶部; - 桌面端没有软键盘带来的视口变化,浏览器对输入框尺寸变更的滚动位置计算更稳定,因此不会出现异常。
修复方案
1. 绑定受控组件的value(必做)
你代码中注释掉了value={description},这会导致textarea成为非受控组件,state与输入框内容可能不同步,加剧异常行为,先恢复绑定:
<Form.Control className="description-input" style={descriptionFont} value={description} // 恢复该绑定 as="textarea" placeholder={placeholder} onChange={(event) => handleTextAreaChange(event)} />
2. 保存并恢复滚动位置
修改textarea高度前,先记录当前滚动位置,调整完成后再重置回去,避免滚动跳顶:
const handleTextAreaChange = (event) => { const textarea = event.target; // 保存当前滚动位置 const scrollTop = textarea.scrollTop; // 重置高度并重新计算 textarea.style.height = 'auto'; textarea.style.height = textarea.scrollHeight + 'px'; // 恢复滚动位置 textarea.scrollTop = scrollTop; // 更新state setDescription(event.target.value); };
3. 优化高度计算(可选)
如果上述方案仍有问题,可使用requestAnimationFrame确保DOM更新完成后再调整高度,避免浏览器重排冲突:
const handleTextAreaChange = (event) => { const textarea = event.target; const scrollTop = textarea.scrollTop; setDescription(event.target.value); requestAnimationFrame(() => { textarea.style.height = 'auto'; textarea.style.height = textarea.scrollHeight + 'px'; textarea.scrollTop = scrollTop; }); };
4. CSS辅助优化
给textarea添加滚动锚点设置,帮助浏览器维持滚动位置:
.blog-form textarea { width: 100%; resize: none; overflow-y: auto; overflow-anchor: auto; /* 添加该行 */ }
内容的提问来源于stack exchange,提问作者Dragos Polifronie
相关产品推荐
相关产品推荐

