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

如何在特定Div上禁用页面滚动但保留滚动交互以切换菜单?

解决方案:禁用页面滚动但保留ScrollTrigger滚动交互逻辑

核心思路

通过阻止目标区域内的原生滚动事件,同时手动模拟滚动进度传递给ScrollTrigger,既避免页面实际滚动,又保留滚动交互触发菜单项切换的逻辑,无需全局设置position:fixed或overflow:hidden。


具体实现步骤

1. 阻止目标区域的原生滚动事件

监听wheel(桌面端)和touchmove(移动端)事件,仅在#wrapper区域内阻止默认滚动行为,同时提取滚动增量用于更新ScrollTrigger进度。

// 阻止#wrapper区域内的桌面端滚动
document.addEventListener('wheel', (e) => {
  const wrapper = document.getElementById('wrapper');
  if (wrapper.contains(e.target)) {
    e.preventDefault();
    // 提取滚动增量,传递给ScrollTrigger
    scrollTriggerInstance.scroll(scrollTriggerInstance.scroll() + e.deltaY);
  }
}, { passive: false });

// 阻止#wrapper区域内的移动端触摸滚动
let lastTouchY = 0;
document.addEventListener('touchmove', (e) => {
  const wrapper = document.getElementById('wrapper');
  if (wrapper.contains(e.target)) {
    e.preventDefault();
    const currentTouchY = e.touches[0].clientY;
    const delta = currentTouchY - lastTouchY;
    lastTouchY = currentTouchY;
    // 转换触摸方向为滚动增量,传递给ScrollTrigger
    scrollTriggerInstance.scroll(scrollTriggerInstance.scroll() - delta);
  }
}, { passive: false });

2. 改造ScrollTrigger实例

将ScrollTrigger实例保存为全局变量,方便手动更新滚动进度;移除scrub配置,改为通过事件触发手动控制。

let scrollTriggerInstance;
let currentMenuItemIndex = 0;
// 确保clamp函数存在(若全局未定义)
function clamp(value, min, max) {
  return Math.min(Math.max(value, min), max);
}

// 初始化ScrollTrigger
scrollTriggerInstance = ScrollTrigger.create({
  trigger: '#wrapper',
  start: 'top top',
  end: 'bottom bottom',
  onUpdate: (self) => {
    const currentScrollDistance = self.scroll();
    // 这里需替换为你实际定义的单段滚动距离(比如每个内容区块的高度)
    const scrollDistance = 300; 
    let newMenuItemIndex = Math.floor(currentScrollDistance / scrollDistance);
    newMenuItemIndex = clamp(newMenuItemIndex, 0, menuItems.length - 1);

    if (newMenuItemIndex !== currentMenuItemIndex) {
      // 移除上一个菜单项的选中状态
      menuItems[currentMenuItemIndex].classList.remove('selected');
      contents[currentMenuItemIndex].querySelectorAll(".tags")
        .forEach(circle => circle.classList.remove('circle'));
      
      // 激活当前菜单项
      menuItems[newMenuItemIndex].classList.add('selected');
      contents[newMenuItemIndex].querySelectorAll(".tags")
        .forEach(circle => circle.classList.add('circle'));
      
      currentMenuItemIndex = newMenuItemIndex;
    }
  }
});

优势说明

  • 仅在目标区域内禁用滚动,页面其他区域可正常滚动(若业务需要)
  • 无需修改全局元素布局,避免position:fixed带来的适配问题
  • 保留原生滚动的交互手感,同时通过手动控制ScrollTrigger进度实现菜单项切换逻辑

内容的提问来源于stack exchange,提问作者omie.soa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:20:32