如何使用JavaScript以其中一个为参考同步两个不同尺寸容器的滚动
双容器同步滚动(同时结束)实现方案
核心逻辑
两个容器内容完全相同,只需保证二者的滚动进度百分比始终一致,即可实现同时滚动到终点:
- 滚动进度百分比 = 当前已滚动距离 / 总可滚动距离
- 总可滚动距离 = 元素scrollHeight - 元素clientHeight
你原代码的核心问题是同步速度的计算逻辑错误,算出来的syncedSpeed和masterSpeed完全相等,没有实现速度适配。
完整实现代码
HTML代码
<div class="container"> <div class="box1" id="master-box">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!<span></span></div> <div class="box2" id="slave-box">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!<span></span></div> </div>
CSS代码
.container { display: flex; } span { display: block; height : 3px; background: red; } .box1{ width: 100px; height: 200px; overflow-y: auto; border: 2px solid blue; margin: 10px; } .box2{ width: 200px; height: 300px; overflow-y: auto; border: 2px solid blue; margin: 10px; }
JS代码
const masterSpeed = 50; // 主容器定时器间隔,单位毫秒 const stepSize = 1; // 主容器每次滚动步长 const masterElement = document.getElementById("master-box"); const slaveElement = document.getElementById("slave-box"); // 计算两个容器的总可滚动距离 const masterTotalScroll = masterElement.scrollHeight - masterElement.clientHeight; const slaveTotalScroll = slaveElement.scrollHeight - slaveElement.clientHeight; let masterScrollPos = 0; window.setInterval(function(){ if (masterScrollPos >= masterTotalScroll) return; // 主容器滚到底后停止 masterScrollPos += stepSize; // 主容器滚动 masterElement.scrollTo({ top: masterScrollPos, behavior: 'smooth' }); // 按比例计算从容器应该滚动到的位置 const progress = masterScrollPos / masterTotalScroll; const slaveScrollPos = progress * slaveTotalScroll; slaveElement.scrollTo({ top: slaveScrollPos, behavior: 'smooth' }); }, masterSpeed);
实现说明
- 只需要一个定时器控制主容器滚动即可,从容器的滚动位置直接通过进度比例换算得出,不需要单独开定时器,避免不同定时器的执行误差导致不同步
- 主容器和从容器的滚动进度始终对齐,因此会同时滚动到底部
内容的提问来源于stack exchange,提问作者Zoli
相关产品推荐
相关产品推荐

