监听input元素focus事件时,如何阻止移动端多余滚动?
解决方案
问题核心在于:用户手动点击/触摸input时,浏览器会先执行默认滚动到input的行为,之后才触发focus事件,此时在focus事件里调用preventDefault已经无法阻止之前的默认滚动。另外你尝试设置的event.preventScroll = true是主动调用focus()方法时的配置选项,并非focus事件对象的属性,所以完全不起作用。
要实现需求,你需要在浏览器触发默认滚动之前拦截操作,手动控制聚焦和滚动:
代码实现
const inputTextElement = document.getElementById('your-input-id'); const targetElement = document.getElementById('another_element'); // 处理移动端触摸事件 inputTextElement.addEventListener('touchstart', (e) => { // 阻止浏览器默认的触摸行为(包括自动滚动到input) e.preventDefault(); // 手动聚焦input,同时阻止默认滚动 inputTextElement.focus({ preventScroll: true }); // 滚动到目标元素 targetElement.scrollIntoView(); }); // 可选:处理桌面端点击(如果需要统一逻辑) inputTextElement.addEventListener('mousedown', (e) => { e.preventDefault(); inputTextElement.focus({ preventScroll: true }); targetElement.scrollIntoView(); });
为什么这样有效?
touchstart/mousedown事件会在浏览器执行默认滚动行为之前触发,此时调用e.preventDefault()可以阻止浏览器自动滚动到input元素。- 手动调用
focus({ preventScroll: true })确保input获得焦点,同时不会触发浏览器的默认滚动逻辑。 - 最后执行
scrollIntoView()只触发一次目标元素的滚动,避免过度滚动。
内容的提问来源于stack exchange,提问作者Backo
相关产品推荐
相关产品推荐

