React - 循环滚动

1.准备工作

  let timer = null; // 定时器
  const BoxRef = useRef(); // 父组件ref
  const ChildRef = useRef(); // 子组件ref用于包裹数据循环的
  const [roll, setRoll] = useState(true); // 是否滚动
  // comments是要map的数据

2.开始

  1. 鼠标移入时暂停
  2. 移出时开始
  3. 移入时上下滚动 无缝循环滚动
/**
用做于自动向上循环滚动
**/
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}
        onMouseEnter={() => setRoll(false)} // 鼠标移入移出都修改roll的值 从而更新定时器和关闭
        onMouseLeave={() => 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>

 

posted @   马铃薯头抽雪茄  阅读(373)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示