1.准备工作
let timer = null; // 定时器
const BoxRef = useRef(); // 父组件ref
const ChildRef = useRef(); // 子组件ref用于包裹数据循环的
const [roll, setRoll] = useState(true); // 是否滚动
// comments是要map的数据
2.开始
- 鼠标移入时暂停
- 移出时开始
- 移入时上下滚动 无缝循环滚动
/**
用做于自动向上循环滚动
**/
useEffect(() => {
// 使用定时器
timer = setInterval(() => {
if (!roll) return;
// 判断父组件的滚动高度是否大于子组件本身的高度
// 是的话就回到0 不是即++让他有自动往上移动的效果
if (BoxRef.current.scrollTop >= ChildRef.current.scrollHeight) {
BoxRef.current.scrollTo({
top: 0,
behavior: 'instant',
});
} else {
BoxRef.current.scrollTo({
top: BoxRef.current.scrollTop++,
behavior: 'smooth',
});
}
}, 25);
return () => {
// 数据变化就关闭重新开始一个定时器
clearInterval(timer);
timer = null;
};
}, [comments, roll]);
/**
用作于当鼠标放入时监听滚动 来达到上下滚动过都循环的效果
**/
const scrollChange = () => {
if (roll) return; // 如果当前为允许滚动则跳出
if (BoxRef.current.scrollTop <= 0) {
// 判断父组件滚动的距离是否 向上滚动到0了如果是就跳到子组件的高度
// 这里减一是怕他执行时被下面的代码再一次执行 导致又回到了0然后导致死循环
BoxRef.current.scrollTo({
top: ChildRef.current.scrollHeight - 1,
behavior: 'instant',
});
} else if (BoxRef.current.scrollTop >= ChildRef.current.scrollHeight) {
// 判断父组件的滚动的距离是否大于子组件的高度
// 这里回到1而不是0 也是同上↑
BoxRef.current.scrollTo({
top: 1,
behavior: 'instant',
});
}
};
useEffect(() => {
BoxRef.current?.addEventListener('scroll', scrollChange, true);
return () => {
BoxRef.current?.removeEventListener('scroll', scrollChange, true);
};
}, [roll]);
结构
/**
Test 封装的组件忽略
**/
<div
width="match_parent"
height="wrap_content"
display="flex"
flexDirection="column"
overflow={roll ? 'hidden' : 'auto'}
ref={BoxRef}
onm ouseEnter={() => setRoll(false)}
onm ouseLeave={() => setRoll(true)}
>
<div
width="match_parent"
height="wrap_content"
ref={ChildRef}
display="flex"
flexDirection="column"
>
{comments?.map(comment => (
<Test
key={comment.getId()}
width="match_parent"
height="wrap_content"
/>
))}
</div>
<div
width="match_parent"
height="wrap_content"
display="flex"
flexDirection="column"
>
{comments?.map(comment => (
<Test
key={comment.id}
width="match_parent"
height="wrap_content"
/>
))}
</div>
</div>
标签:current,滚动,React,循环,组件,const,BoxRef,roll From: https://www.cnblogs.com/Dluea/p/17503574.html