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

如何实现特定div的滚动行为切换:垂直转水平后恢复默认?

多段垂直转水平滚动Section的实现方案

一、成熟库推荐

  • ScrollTrigger(GSAP生态):这是实现滚动交互的主流工具,原生支持滚动位置监听,能精准触发垂直到水平的滚动切换逻辑,而且天生支持多段独立的滚动区块,每个section可单独配置触发条件和滚动行为,不需要额外做太多兼容性处理。
  • Locomotive Scroll:轻量级自定义滚动库,支持通过监听滚动位置,结合CSS transform实现垂直转水平的滚动切换,对多区块场景的兼容性很好,配置也相对灵活。

二、原生JS自行实现思路

如果不想依赖第三方库,核心是通过监听页面滚动事件,控制目标section的滚动行为,步骤如下:

1. DOM结构准备

给每个需要切换滚动的section添加统一类名(比如horizontal-scroll-section),内部嵌套一个容器承载水平内容:

<section class="horizontal-scroll-section">
  <div class="scroll-inner">
    <div class="scroll-item">区块内容1</div>
    <div class="scroll-item">区块内容2</div>
    <!-- 更多水平内容 -->
  </div>
</section>

2. 基础样式配置

设置section固定高度,内部容器自适应宽度以容纳所有水平内容,默认保持垂直滚动:

.horizontal-scroll-section {
  height: 100vh; /* 占满视口高度,明确触发边界 */
  overflow: hidden;
  position: relative;
}
.scroll-inner {
  display: flex;
  width: max-content;
  height: 100%;
}
.scroll-item {
  width: 100vw;
  height: 100%;
}

3. 核心滚动逻辑

  • 监听页面滚动,判断每个section的位置是否进入触发范围;
  • 当section顶部到达视口顶部且未滚到右侧尽头时,拦截默认垂直滚动,将垂直滚动量转化为内部容器的水平偏移;
  • 滚到右侧尽头或离开section范围后,恢复默认垂直滚动。

核心代码示例:

const horizontalSections = document.querySelectorAll('.horizontal-scroll-section');
let isScrollLocked = false;

// 节流函数优化性能
function throttle(func, delay) {
  let lastCall = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastCall >= delay) {
      lastCall = now;
      return func(...args);
    }
  };
}

const handleScroll = throttle((e) => {
  horizontalSections.forEach(section => {
    const rect = section.getBoundingClientRect();
    const innerContainer = section.querySelector('.scroll-inner');
    const maxHorizontalScroll = innerContainer.scrollWidth - section.clientWidth;
    const sectionOffsetTop = section.offsetTop;

    // 进入触发范围:section在视口内,且未滚到右侧尽头
    if (rect.top <= 0 && rect.bottom > 0 && innerContainer.scrollLeft < maxHorizontalScroll) {
      isScrollLocked = true;
      e.preventDefault();
      // 将垂直滚动距离转为水平偏移
      const verticalScrollAmount = window.scrollY - sectionOffsetTop;
      innerContainer.scrollLeft = verticalScrollAmount;
    } 
    // 滚到右侧尽头,解锁垂直滚动
    else if (innerContainer.scrollLeft >= maxHorizontalScroll) {
      isScrollLocked = false;
    }
    // 离开section范围,重置状态
    else {
      isScrollLocked = false;
      innerContainer.scrollLeft = 0; // 可选:离开后重置水平位置
    }
  });
}, 16);

window.addEventListener('scroll', handleScroll);
// 处理触摸滚动
window.addEventListener('touchmove', (e) => {
  if (isScrollLocked) e.preventDefault();
}, { passive: false });

4. 关键优化点

  • 用节流函数减少滚动事件触发频率,避免性能损耗;
  • 处理触摸滚动事件,确保移动端行为一致;
  • 给每个section独立维护状态,避免多区块之间的逻辑冲突;
  • 可添加过渡动画,让滚动切换更平滑(比如给scroll-inner的scrollLeft添加transition)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:05:56