reactjs 如何在当前节中加粗文本

mitkmikd  于 2022-11-04  发布在  React
关注(0)|答案(1)|浏览(207)

我在一个网站上有不同的部分(都在同一个页面上),而且我还有一个导航栏,它总是固定在顶部。我希望当我停留在该部分时,导航栏中的文本是粗体的,表明我在那里,我如何才能做到这一点?
以下是应用程序的结构:

  1. export default function Main() {
  2. return (
  3. <div className="App relative">
  4. <NavBar fixed />
  5. <Home />
  6. <Purpose />
  7. <WhoWeAre />
  8. <FinancialSolutions />
  9. <Products />
  10. <ComercialPartners/>
  11. <SocialMedia />
  12. <Footer />
  13. </div>
  14. );
  15. }

所有的组件都在不同的文件中,每个组件都有它们的id标签。导航栏有除了页脚之外的每一部分。

noj0wjuj

noj0wjuj1#

您可以使用交叉点观察器来实现这一点。交叉点观察器会检测当前屏幕上的元素。您的情况很棘手,因为您需要检测您首先滚动的方向。因为当您向下滚动时,您想要在某个部分的标题在页面顶部消失时表示您正在该部分中。但是当你向上滚动的时候,你想说的是当这个部分的标题出现在页面的顶部时,你就在这个部分中了。所以首先我们需要检测滚动的方向,然后检测哪个元素出现或消失。
钩子返回引用。你必须给予你的代码中的元素一个引用,你想检测它们是否相交。比如:const [idVisible, setIdVisible] = useState("");
你的主组件需要实现const [idVisible, setIdVisible] = useState("");然后将'idVisible传递给你的导航栏来决定哪一个应该突出显示。
另一个useState const [clickedSection, setIsClickedSection] = useState(false);可能不需要。这取决于当你点击导航栏中的一个部分时,它是否会导航到页面上的该部分。如果是这样的话,你需要将setIsClickedSection函数也传递到你的导航栏。当你点击一个链接时,你需要将它设置为'true'。原因是导航到一个部分会触发滚动,并会产生奇怪的结果。这有点复杂。我花了一两天的时间才得到这个结果。如果你的最后一部分很小,它可能永远不会在屏幕的顶部相交。处理这个问题的一个方法是使用来检测你是否到达了页面的底部,然后setIdVisible到页面的最后一部分。
这是我为类似目的制作的钩子:

  1. export const ShowSectionHook = (clickedSection: boolean, setIsClickedSection: (value: boolean) => void, setIdVisible: (value: string) => void, window: Window, lastSectionId: string, firstId?: string) => {
  2. const ref1 = useRef(null);
  3. const ref2 = useRef(null);
  4. const ref3 = useRef(null);
  5. const ref4 = useRef(null);
  6. const ref5 = useRef(null);
  7. useEffect(() => {
  8. //Scroll listener to determine the scroll direction
  9. const threshold = 0;
  10. let lastScrollY = window.scrollY;
  11. let scrollDir = "";
  12. const updateScrollDir = () => {
  13. const scrollY = window.scrollY;
  14. if (Math.abs(scrollY - lastScrollY) < threshold) {
  15. return;
  16. }
  17. scrollDir = (scrollY > lastScrollY ? "scrolling down" : "scrolling up");
  18. lastScrollY = scrollY > 0 ? scrollY : 0;
  19. };
  20. const onScroll = () => {
  21. window.requestAnimationFrame(updateScrollDir);
  22. };
  23. window.addEventListener("scroll", onScroll);
  24. //interjection observer to detect if the element is on the page
  25. const element1 = ref1.current;
  26. const element2 = ref2.current;
  27. const element3 = ref3.current;
  28. //create one for each section you have
  29. const observer = new IntersectionObserver(
  30. ([entry]) => {
  31. if (scrollDir === "scrolling down" && entry && !entry.isIntersecting && !clickedSection) {
  32. setIdVisible(entry.target.id);
  33. }
  34. if (scrollDir === "scrolling up" && entry && entry.isIntersecting && !clickedSection) {
  35. setIdVisible(entry.target.id);
  36. }
  37. setIsClickedSection(false);
  38. },
  39. {
  40. root: null, //viewport
  41. rootMargin: "0px",
  42. threshold: 1, //this means that the element get detected when 100% of the card is visible
  43. })
  44. if (element1) {
  45. observer.observe(element1);
  46. }
  47. if (element2) {
  48. observer.observe(element2);
  49. }
  50. if (element3) {
  51. observer.observe(element3);
  52. }
  53. return () => {
  54. observer.disconnect()
  55. window.removeEventListener("scroll", onScroll);
  56. }
  57. }, [clickedSection, setIdVisible, setIsClickedSection, window, lastSectionId, firstId])
  58. return {ref1: ref1, ref2: ref2, ref3: ref3}
  59. }
展开查看全部

相关问题