前言:
最近公司有一个功能模块需要实现切换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;