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

如何实现左侧滚动div触底后右侧固定div同步滚动的布局效果

实现类似商品详情页的滚动固定布局

核心逻辑:桌面端滚动时,右侧商品详情栏先保持固定定位,直到左侧图片区域完全滚出视口后,右侧栏恢复随页面正常滚动。以下是具体实现方案:

HTML 结构

采用基础的两栏布局,左侧放置商品图片列表,右侧承载详情内容:

<div class="product-page">
  <div class="left-column">
    <div class="product-image">商品图片1</div>
    <div class="product-image">商品图片2</div>
    <div class="product-image">商品图片3</div>
    <div class="product-image">商品图片4</div>
    <div class="product-image">商品图片5</div>
  </div>
  <div class="right-column">
    <h1>Gymshark Vital Seamless 2.0 Light T-Shirt</h1>
    <div class="price">$45.00</div>
    <div class="size-selector">尺寸选择器...</div>
    <button class="add-to-cart">加入购物车</button>
    <div class="product-description">
      这里是商品详情描述,建议填充足够多的内容,以测试滚动跟随效果...
    </div>
  </div>
</div>

CSS 基础样式

实现响应式布局,桌面端分栏展示,移动端自动堆叠;为固定状态的右侧栏预留定位规则:

/* 基础样式重置 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.product-page {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

/* 移动端默认堆叠 */
.left-column, .right-column {
  width: 100%;
}

.product-image {
  height: 400px;
  background-color: #f0f0f0;
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}

.right-column {
  padding: 20px;
  position: relative; /* 默认相对定位 */
}

/* 桌面端分栏布局 */
@media (min-width: 1024px) {
  .product-page {
    display: flex;
    gap: 40px;
  }
  
  .left-column {
    width: 50%;
  }
  
  .right-column {
    width: 50%;
  }
  
  /* 固定状态样式 */
  .right-column.fixed {
    position: fixed;
    top: 20px;
    right: calc((100vw - 1200px)/2 + 20px); /* 对齐容器右侧间距 */
  }
}

JavaScript 滚动逻辑

监听滚动事件,计算关键位置阈值,动态切换右侧栏的固定状态:

const leftColumn = document.querySelector('.left-column');
const rightColumn = document.querySelector('.right-column');

// 存储关键布局参数
let rightColumnOffsetTop;
let leftColumnTotalHeight;
let rightColumnWidth;

// 初始化/更新布局参数
function initLayoutValues() {
  const rightRect = rightColumn.getBoundingClientRect();
  rightColumnOffsetTop = rightRect.top + window.scrollY;
  rightColumnWidth = rightRect.width;
  leftColumnTotalHeight = leftColumn.offsetHeight;
}

// 页面加载及窗口 resize 时更新参数
window.addEventListener('load', initLayoutValues);
window.addEventListener('resize', initLayoutValues);

// 监听滚动事件
window.addEventListener('scroll', () => {
  const scrollY = window.scrollY;
  // 固定状态的触发区间:
  // 1. 滚动距离 >= 右侧栏初始顶部位置
  // 2. 滚动距离 <= 左侧栏总高度 - 视口高度 + 右侧栏初始顶部位置(左侧栏即将滚完)
  const fixedStart = rightColumnOffsetTop;
  const fixedEnd = leftColumnTotalHeight - window.innerHeight + rightColumnOffsetTop;

  if (scrollY >= fixedStart && scrollY <= fixedEnd) {
    rightColumn.classList.add('fixed');
    rightColumn.style.width = `${rightColumnWidth}px`; // 固定宽度避免布局偏移
  } else {
    rightColumn.classList.remove('fixed');
    rightColumn.style.width = ''; // 恢复默认宽度
  }
});

关键细节说明

  • 固定状态的右侧栏通过动态获取初始宽度,避免因屏幕尺寸变化导致的布局偏移;
  • 窗口 resize 时重新计算布局参数,保证响应式场景下的正确性;
  • fixedEnd 阈值的计算逻辑:当滚动到该位置时,左侧图片区域的底部刚好进入视口,此时右侧栏恢复正常滚动,避免出现内容脱节。

内容的提问来源于stack exchange,提问作者Umair Khan Jadoon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:54:24