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

如何实现分段滚动:先滚左侧列到底后自动滚右侧列再共同上移?

实现分段式双列滚动逻辑

先调整HTML结构,给关键元素加标识方便后续JS定位:

<section id="intro-section">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</section>

<section id="columns-section">
  <div class='column-left' id="column-left">
    <!-- 填充足够内容才能看到滚动效果 -->
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  </div>

  <div class='column-right' id="column-right">
    <!-- 填充足够内容才能看到滚动效果 -->
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  </div>
</section>

<section class="bottom-section">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</section>

<section class="bottom-section">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</section>

<section class="bottom-section">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</section>

修改CSS,添加状态类控制不同阶段的显示:

#columns-section {
  position: relative;
  min-height: 100vh;
  width: 100%;
  overflow: hidden;
  transition: transform 0.5s ease-out;
}

.column-left {
  width: 74%;
  max-height: 100vh;
  -ms-overflow-style: none;
  scrollbar-width: none;
  overflow-y: hidden;
  float: left;
  padding-bottom: 2rem;
  background-color: #fff;
  position: sticky;
  top: 0;
}

.column-left::-webkit-scrollbar {
  display: none;
}

.column-left.scrollable {
  overflow-y: scroll;
}

.column-left:hover{
  scroll-behavior: smooth;
}

.column-right {
  width: 26%;
  max-height: 100vh;
  overflow-y: hidden;
  -ms-overflow-style: none;
  scrollbar-width: none;
  float: right;
  padding: 0rem 3rem 6rem;
  margin: 0 auto;
  background-color: #00185a;
  color: #fff;
  position: sticky;
  top: 0;
}

.column-right::-webkit-scrollbar {
  display: none; 
}

.column-right.scrollable {
  overflow-y: scroll;
}

.column-right img {
  width: 100%;
  max-width: 396px;
}

#columns-section.exit {
  transform: translateY(-100%);
}

.bottom-section {
  min-height: 100vh;
  padding: 2rem;
}

核心JS逻辑,监听滚动实现分段控制:

const introSection = document.getElementById('intro-section');
const columnsSection = document.getElementById('columns-section');
const columnLeft = document.getElementById('column-left');
const columnRight = document.getElementById('column-right');

let isLeftScrollable = false;
let isLeftAtBottom = false;
let isRightScrollable = false;
let isRightAtBottom = false;
let hasExited = false;

window.addEventListener('scroll', () => {
  if (hasExited) return;

  // 判断第一个section是否完全滚出视口
  const introRect = introSection.getBoundingClientRect();
  const introIsOut = introRect.bottom <= 0;

  // 阶段1:开启左列滚动
  if (introIsOut && !isLeftScrollable) {
    columnLeft.classList.add('scrollable');
    isLeftScrollable = true;
  }

  // 判断左列是否到底部
  if (isLeftScrollable && !isLeftAtBottom) {
    const leftIsAtBottom = columnLeft.scrollTop + columnLeft.clientHeight >= columnLeft.scrollHeight - 10;
    if (leftIsAtBottom) {
      isLeftAtBottom = true;
      columnLeft.classList.remove('scrollable');
      columnRight.classList.add('scrollable');
      isRightScrollable = true;
    }
  }

  // 判断右列是否到底部
  if (isRightScrollable && !isRightAtBottom) {
    const rightIsAtBottom = columnRight.scrollTop + columnRight.clientHeight >= columnRight.scrollHeight - 10;
    if (rightIsAtBottom) {
      isRightAtBottom = true;
      columnsSection.classList.add('exit');
      hasExited = true;
      // 动画结束后释放位置,让下方内容正常显示
      setTimeout(() => {
        columnsSection.style.position = 'absolute';
        columnsSection.style.top = '0';
      }, 500);
    }
  }
});

// 页面刷新时重置状态
window.addEventListener('load', () => {
  isLeftScrollable = false;
  isLeftAtBottom = false;
  isRightScrollable = false;
  isRightAtBottom = false;
  hasExited = false;
  columnLeft.classList.remove('scrollable');
  columnRight.classList.remove('scrollable');
  columnsSection.classList.remove('exit');
  columnsSection.style.position = 'relative';
});

关键逻辑说明

  1. 阶段触发:通过getBoundingClientRect()检测第一个section是否完全离开视口,触发左列滚动。
  2. 底部检测:用scrollTop + clientHeight >= scrollHeight判断列内容是否滚到底,减10px是为了兼容浏览器滚动精度误差。
  3. 状态切换:左列到底后关闭自身滚动、开启右列滚动;右列到底后触发双列移出动画,动画结束后修改布局让下方内容正常显示。
  4. 刷新重置:页面加载时重置所有状态和样式,避免残留状态影响初始显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:45:20