如何阻止textarea获焦时自动滚动到光标位置?
如何让textarea通过JS获焦时不自动滚动到光标位置?
默认情况下调用textarea.focus()时,浏览器会自动将滚动位置调整到光标所在的可见区域,这会打断手动控制的滚动行为。以下是几种解决方法:
方法1:使用preventScroll参数(推荐)
现代浏览器(Chrome 64+、Firefox 55+)支持在focus()方法中传入配置参数,直接阻止自动滚动:
txtarea.focus({ preventScroll: true });
把blur事件监听里的txtarea.focus()换成这个,就能避免获焦时的滚动跳转。针对按钮滚动场景,修改后的代码示例:
const txtarea = document.getElementById("textbox"); const scrollToBottomBtn = document.getElementById("scrollBottom"); // 点击按钮滚动到底部 scrollToBottomBtn.addEventListener('click', () => { txtarea.scrollTo({top: txtarea.scrollHeight, behavior: "smooth"}); }); // blur时重新获焦,阻止自动滚动 txtarea.addEventListener('blur', () => { txtarea.focus({ preventScroll: true }); });
方法2:兼容旧浏览器的 fallback 方案
如果需要支持更老的浏览器,可以先记录textarea当前的滚动位置,调用focus后再恢复滚动:
txtarea.addEventListener('blur', () => { // 记录当前滚动位置 const scrollTop = txtarea.scrollTop; // 获焦 txtarea.focus(); // 立即恢复滚动位置 txtarea.scrollTop = scrollTop; });
这个方法利用JS执行的同步特性,在浏览器自动滚动前强制恢复原来的位置,能达到类似效果。
针对最小复现示例的修改
把原示例中的setTimeout代码改成带preventScroll参数的版本,就能看到获焦时不会自动滚动到光标位置:
<!DOCTYPE html> <html> <head> </head> <body> <textarea rows="20" cols="30" id="textbox"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac tellus a tortor aliquam placerat in tincidunt neque. Fusce a sapien lacus. Aliquam suscipit condimentum tempor. Vestibulum dignissim turpis in ipsum rhoncus, sed porttitor urna suscipit. Phasellus varius diam at elit eleifend dignissim. Donec id condimentum tellus, vitae elementum ex. Fusce scelerisque, nisl vel condimentum hendrerit, nulla magna dictum lacus, ac euismod metus ipsum at felis. Curabitur rutrum molestie accumsan. Cras vitae lobortis metus. Curabitur gravida, erat ut congue ullamcorper, metus nibh auctor ex, a ultricies libero elit quis risus. In gravida ipsum a mi interdum egestas. Nam eu ante molestie, semper mi vitae, hendrerit ligula. Duis ac semper orci. Vestibulum sapien nunc, eleifend id gravida a, aliquet quis erat. Vestibulum porttitor vel neque sed vehicula. Aliquam dignissim lorem tortor, eget rhoncus tortor rutrum nec. Nunc aliquam nisi sed mauris condimentum lacinia. Suspendisse tristique luctus vulputate. Integer efficitur, sem in iaculis porttitor, risus arcu consequat tellus, quis ultrices eros libero vitae elit. Aenean diam ipsum, fringilla sed arcu sed, blandit posuere justo. Maecenas porttitor est quis commodo sollicitudin. Sed justo nibh, gravida id velit dignissim, aliquet viverra lacus. In non ligula luctus, malesuada justo quis, placerat velit. Nullam justo massa, blandit a sapien nec, pellentesque gravida nisl. Sed pellentesque sit amet nunc molestie egestas. Nullam ultrices orci non sagittis maximus. Vestibulum cursus vel velit malesuada mollis. Sed dapibus, massa quis suscipit dictum, ligula metus vehicula est, vel tincidunt magna quam ut orci. Aenean aliquet rutrum metus et finibus. </textarea> <script> const txtarea = document.getElementById("textbox"); setTimeout(() => { txtarea.focus({ preventScroll: true }); }, 8000); </script> </body> </html>
内容的提问来源于stack exchange,提问作者AlanQ
相关产品推荐
相关产品推荐

