React切换Tab栏并进行锚点滚动

前言:

最近公司有一个功能模块需要实现切换Tab栏之后跳转到对应锚点位置的功能,我研究之后写了一个自定义钩子,现在分享给小伙伴们,有需要可以直接使用提升工作效率。

1.安装react-scroll-to

npm install react-scroll-to

2.封装 useScrollIntoView钩子

javascript 复制代码
import { useRef, useEffect } from "react";

function useScrollIntoView() {
  const targetRef = useRef(null);
  function scrollToTarget() {
    if (targetRef.current) {
//targetRef.current.getBoundingClientRect().top获取当前元素的相对于视口顶部的高度
//document.documentElement.scrollTop:获取整个文档在垂直方向上滚动的距离
      const topPosition =
        targetRef.current.getBoundingClientRect().top +
        document.documentElement.scrollTop;
      window.scrollTo({
        top: topPosition - 49, // 设置距离顶部的偏移量即顶部导航的高度也可以通过getBoundingClientRect获取准确值
        behavior: "smooth",
      });
    }
  }
  useEffect(() => {
    // 在组件挂载后立即滚动到目标元素
    scrollToTarget();
  }, []);

  return {
    targetRef,
    scrollToTarget,
  };
}

export default useScrollIntoView;

3.在页面中使用

javascript 复制代码
import useScrollIntoView from "@utils/useScrollIntoView"; //自定义滚动hook
const [activeTab, setActiveTab] = useState("复习单词");
const TodayToWords = () => {
  const { targetRef: reviewWords, scrollToTarget: scrollToAnchor1 } =
    useScrollIntoView();
  const { targetRef: newWords, scrollToTarget: scrollToAnchor2 } =
    useScrollIntoView();
  const { targetRef: unFinish, scrollToTarget: scrollToAnchor3 } =
    useScrollIntoView();
  //切换tab栏
  const handleTabClick = (tab) => {
    setActiveTab(tab);
    if (tab === "复习单词") {
      scrollToAnchor1();
    } else if (tab === "新学单词") {
      scrollToAnchor2();
    } else if (tab === "未学完单词") {
      scrollToAnchor3();
    }
  };
  const WordList = ({
    words,
    targetRef = null,
  }) => {
 return ({words.length > 0 && (
           <div
                  className={styles["word-item-content"]}
                  onClick={() => {
                     handleGetReviewWordsRead(item, idx);
                    }}
                  >
                    <span className={styles["word"]}>{item.word}</span>
                    <span className={styles["score"]}>
                      {`学习进度${
                        Number(item.score) >= 10
                          ? 100
                          : (Number(item.score) / 10) * 100
                      }%`}
                    </span>
            </div>
      )
   }      
)
return (
       <div className={styles["learn-container"]}>
        <div className={styles["learn-container-tab"]}>
          {reviewFinishedWords.length > 0 && (
            <div
              onClick={() => {
                handleTabClick("复习单词");
              }}
              className={`${
                activeTab === "复习单词" ? styles.active : ""
              }`}
            >
              {textFront.reviewFinishedWords}
            </div>
          )}
          {newFinishedWords.length > 0 && (
            <div
              onClick={() => {
                handleTabClick("新学单词");
              }}
              className={`${
                activeTab === "新学单词" ? styles.active : ""
              }`}
            >
              {textFront.newFinishedWords}
            </div>
          )}
          {unFinishedWords.length > 0 && (
            <div
              onClick={() => {
                handleTabClick("未学完单词");
              }}
              className={`${
                activeTab === "未学完单词" ? styles.active : ""
              }`}
            >
              {textFront.unFinishedWords}
            </div>
          )}
        </div>
        {/* 自定义组件,点击切换Tab栏时的滚动区域 */}
        <WordList
          words={reviewFinishedWords}
          targetRef={reviewWords}
        />
        <WordList
          words={newFinishedWords}
          targetRef={newWords}
        />
        <WordList
          words={unFinishedWords}
          targetRef={unFinish}
        />
      </div>
)
}
export default TodayToWords;
相关推荐
小小小小宇7 小时前
虚拟列表兼容老DOM操作
前端
悦悦子a啊7 小时前
Python之--基本知识
开发语言·前端·python
安全系统学习8 小时前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
涛哥码咖8 小时前
chrome安装AXURE插件后无效
前端·chrome·axure
OEC小胖胖8 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水8 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
Sally璐璐9 小时前
零基础学HTML和CSS:网页设计入门
前端·css
老虎06279 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
三水气象台9 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue
灿灿121389 小时前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css