前言:
最近公司有一个功能模块需要实现切换Tab栏之后跳转到对应锚点位置的功能,我研究之后写了一个自定义钩子,现在分享给小伙伴们,有需要可以直接使用提升工作效率。
1.安装react-scroll-to
npm install react-scroll-to
2.封装 useScrollIntoView钩子
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.在页面中使用
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 && (<divclassName={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 && (<divonClick={() => {handleTabClick("复习单词");}}className={`${activeTab === "复习单词" ? styles.active : ""}`}>{textFront.reviewFinishedWords}</div>)}{newFinishedWords.length > 0 && (<divonClick={() => {handleTabClick("新学单词");}}className={`${activeTab === "新学单词" ? styles.active : ""}`}>{textFront.newFinishedWords}</div>)}{unFinishedWords.length > 0 && (<divonClick={() => {handleTabClick("未学完单词");}}className={`${activeTab === "未学完单词" ? styles.active : ""}`}>{textFront.unFinishedWords}</div>)}</div>{/* 自定义组件,点击切换Tab栏时的滚动区域 */}<WordListwords={reviewFinishedWords}targetRef={reviewWords}/><WordListwords={newFinishedWords}targetRef={newWords}/><WordListwords={unFinishedWords}targetRef={unFinish}/></div>
)
}
export default TodayToWords;