如何实现左侧滚动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
相关产品推荐
相关产品推荐

