实现不同高度两个Div的滚动同步
实现不同高度Div的比例同步滚动
要实现两个高度不同的Div按比例同步滚动,核心是基于滚动比例而非固定距离来同步——计算当前滚动元素的滚动距离占其总可滚动高度的百分比,再将这个百分比应用到另一个元素上,就能保证两者始终处于内容的相同比例位置。
实现步骤
- 给两个滚动容器添加滚动属性与高度限制,让内容超出时显示滚动条
- 监听容器滚动事件,计算滚动比例并同步另一个容器的滚动位置
- 处理事件循环触发问题,避免滚动抖动
完整代码示例
HTML
<div class="cont"> <div class="main"></div> <div class="right"></div> </div>
CSS
body { margin: 0; padding: 0; } .box { height: 200px; width: 250px; border: 2px solid red; margin: 10px; display: flex; align-items: center; justify-content: center; font-size: larger; } .cont { display: flex; align-items: flex-start; gap: 20px; padding: 20px; } /* 核心:给滚动容器添加滚动属性和高度限制 */ .main, .right { max-height: 80vh; overflow-y: auto; }
JavaScript
// 初始化测试内容 for (let i = 0; i < 10; i++) { document.querySelector(".right").insertAdjacentHTML("afterbegin", `<div class="box">${10 - i}</div>`); } for (let i = 0; i < 20; i++) { document.querySelector(".main").insertAdjacentHTML("afterbegin", `<div class="box">${20 - i}</div>`); } // 获取滚动容器元素 const main = document.querySelector('.main'); const right = document.querySelector('.right'); // 标记同步状态,避免循环触发滚动事件 let isSyncing = false; // 同步滚动逻辑 function syncScroll(source, target) { if (isSyncing) return; isSyncing = true; // 计算滚动比例:当前滚动距离 / 总可滚动高度 const scrollRatio = source.scrollTop / (source.scrollHeight - source.clientHeight); // 将比例应用到目标容器 target.scrollTop = scrollRatio * (target.scrollHeight - target.clientHeight); // 延迟释放同步标记,避免事件冲突 setTimeout(() => { isSyncing = false; }, 10); } // 绑定滚动事件 main.addEventListener('scroll', () => syncScroll(main, right)); right.addEventListener('scroll', () => syncScroll(right, main));
关键细节说明
- 滚动比例计算:
scrollHeight - clientHeight是容器的总可滚动高度(内容总高度减去容器可视区域高度),用当前滚动距离除以这个值就能得到滚动的百分比。 - 防抖动处理:
isSyncing变量用来标记是否正在执行同步操作,避免设置目标容器滚动位置时触发其滚动事件,造成循环调用和页面抖动。 - 容器样式要求:必须给容器设置
overflow-y: auto和固定/最大高度,否则不会生成滚动条,也就无法触发滚动事件。
内容的提问来源于stack exchange,提问作者vatsal
相关产品推荐
相关产品推荐

