You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何禁止用户滚动div但允许JavaScript控制其滚动?

解决思路与方案

要实现禁止用户手动滚动但允许JavaScript控制滚动的需求,可通过以下几种可靠方案实现:

方案1:精准拦截用户触发滚动的输入事件

用户手动滚动的触发方式有限,主要包括鼠标滚轮、触摸滑动、键盘按键(上下箭头、PageUp/PageDown等)。我们可以监听这些事件并阻止默认行为,同时保留容器的overflow: auto属性,确保JS的滚动方法正常生效。

修改后的代码:

JavaScript

const btn = document.querySelector('button#scroll');
const cnt = document.querySelector('div#container');

btn.addEventListener('click', e => {
  cnt.scrollTo(20, 500);
});

// 拦截鼠标滚轮事件
cnt.addEventListener('wheel', (e) => {
  e.preventDefault();
}, { passive: false });

// 拦截触摸滑动事件
cnt.addEventListener('touchmove', (e) => {
  e.preventDefault();
}, { passive: false });

// 拦截键盘滚动相关按键
cnt.addEventListener('keydown', (e) => {
  const scrollTriggerKeys = ['ArrowUp', 'ArrowDown', 'PageUp', 'PageDown', ' ', 'Home', 'End'];
  if (scrollTriggerKeys.includes(e.key)) {
    e.preventDefault();
  }
});

CSS(保持原隐藏滚动条样式)

div#container {
  width: 400px;
  height: 400px;
  overflow-y: auto;
  scroll-behavior: smooth;
  -ms-overflow-style: none;
  scrollbar-width: none;
}
div#container::-webkit-scrollbar {
  display: none;
}

方案2:通过标志位区分JS与用户触发的滚动

设置一个标志位标记当前滚动是否由JS发起,在scroll事件中判断:若为用户触发的滚动,则强制恢复到之前的位置;若为JS触发,则正常执行并更新记录的滚动位置。

代码示例:

const btn = document.querySelector('button#scroll');
const cnt = document.querySelector('div#container');
let isJsInitiatedScroll = false;
let lastScrollPos = {
  left: cnt.scrollLeft,
  top: cnt.scrollTop
};

btn.addEventListener('click', e => {
  isJsInitiatedScroll = true;
  cnt.scrollTo(20, 500);
});

// 监听滚动结束事件,重置标志位(适配平滑滚动)
cnt.addEventListener('scrollend', () => {
  isJsInitiatedScroll = false;
  // 更新记录的滚动位置
  lastScrollPos = {
    left: cnt.scrollLeft,
    top: cnt.scrollTop
  };
});

cnt.addEventListener('scroll', () => {
  if (!isJsInitiatedScroll) {
    // 非JS触发的滚动,强制恢复到之前的位置
    cnt.scrollTo(lastScrollPos.left, lastScrollPos.top);
  }
});

方案3:临时切换overflow属性

初始设置容器overflow: hidden禁止滚动,当需要JS执行滚动时,临时切换为overflow: auto,滚动完成后再切回hidden。

代码示例:

JavaScript

const btn = document.querySelector('button#scroll');
const cnt = document.querySelector('div#container');

btn.addEventListener('click', e => {
  // 临时开启滚动能力
  cnt.style.overflowY = 'auto';
  cnt.scrollTo(20, 500);
  // 滚动结束后关闭滚动
  cnt.addEventListener('scrollend', () => {
    cnt.style.overflowY = 'hidden';
  }, { once: true });
});

CSS

div#container {
  width: 400px;
  height: 400px;
  overflow-y: hidden;
  scroll-behavior: smooth;
}

内容的提问来源于stack exchange,提问作者LuisAFK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:50:28