react实现滚动联动
滚动联动的实现方法
滚动联动通常指多个滚动容器(如多个div或窗口)在滚动时保持同步。以下是几种常见的实现方式:
使用scroll事件监听
通过监听滚动事件,手动同步多个容器的滚动位置。需要注意性能优化,避免过度触发事件。
import React, { useEffect, useRef } from 'react';
const ScrollSync = () => {
const leftRef = useRef(null);
const rightRef = useRef(null);
useEffect(() => {
const leftEl = leftRef.current;
const rightEl = rightRef.current;
const handleLeftScroll = () => {
rightEl.scrollTop = leftEl.scrollTop;
};
const handleRightScroll = () => {
leftEl.scrollTop = rightEl.scrollTop;
};
leftEl.addEventListener('scroll', handleLeftScroll);
rightEl.addEventListener('scroll', handleRightScroll);
return () => {
leftEl.removeEventListener('scroll', handleLeftScroll);
rightEl.removeEventListener('scroll', handleRightScroll);
};
}, []);
return (
<div style={{ display: 'flex' }}>
<div
ref={leftRef}
style={{ overflowY: 'scroll', height: '300px', width: '50%' }}
>
{/* 左侧内容 */}
</div>
<div
ref={rightRef}
style={{ overflowY: 'scroll', height: '300px', width: '50%' }}
>
{/* 右侧内容 */}
</div>
</div>
);
};
使用第三方库
react-scroll-sync是一个专门用于实现滚动同步的库,简化了实现过程。
import ScrollSync from 'react-scroll-sync';
const ScrollSyncExample = () => (
<ScrollSync>
<div style={{ display: 'flex' }}>
<div style={{ overflowY: 'scroll', height: '300px', width: '50%' }}>
{/* 左侧内容 */}
</div>
<div style={{ overflowY: 'scroll', height: '300px', width: '50%' }}>
{/* 右侧内容 */}
</div>
</div>
</ScrollSync>
);
自定义Hook实现 可以封装一个自定义Hook来复用滚动同步逻辑。

import { useEffect, useRef } from 'react';
const useScrollSync = (...refs) => {
useEffect(() => {
const handlers = refs.map((ref, index) => {
return () => {
refs.forEach((otherRef, otherIndex) => {
if (index !== otherIndex && otherRef.current) {
otherRef.current.scrollTop = ref.current.scrollTop;
}
});
};
});
refs.forEach((ref, index) => {
if (ref.current) {
ref.current.addEventListener('scroll', handlers[index]);
}
});
return () => {
refs.forEach((ref, index) => {
if (ref.current) {
ref.current.removeEventListener('scroll', handlers[index]);
}
});
};
}, [refs]);
};
const ScrollSyncWithHook = () => {
const leftRef = useRef(null);
const rightRef = useRef(null);
useScrollSync(leftRef, rightRef);
return (
<div style={{ display: 'flex' }}>
<div ref={leftRef} style={{ overflowY: 'scroll', height: '300px', width: '50%' }}>
{/* 左侧内容 */}
</div>
<div ref={rightRef} style={{ overflowY: 'scroll', height: '300px', width: '50%' }}>
{/* 右侧内容 */}
</div>
</div>
);
};
性能优化建议
滚动事件会频繁触发,可能影响性能。可以通过以下方式优化:
节流处理
使用lodash.throttle或自定义节流函数减少事件触发频率。

import { throttle } from 'lodash';
// 在事件监听中使用
leftEl.addEventListener('scroll', throttle(handleLeftScroll, 50));
被动事件监听
添加{ passive: true }选项提高滚动性能。
leftEl.addEventListener('scroll', handleLeftScroll, { passive: true });
避免布局抖动
同步操作可能引起重排,使用requestAnimationFrame优化。
const handleScroll = () => {
requestAnimationFrame(() => {
rightEl.scrollTop = leftEl.scrollTop;
});
};
横向滚动联动
横向滚动的实现原理与纵向类似,只需修改scrollLeft属性。
const handleScroll = () => {
rightEl.scrollLeft = leftEl.scrollLeft;
};
注意事项
- 循环触发问题:在同步滚动时需防止事件循环触发。
- 容器高度:确保滚动容器有明确的高度和
overflow属性。 - 移动端兼容性:测试在移动设备上的表现,可能需要额外处理触摸事件。






