reactjs React:当滚动到具有此锚的部分时更新URL锚

nzkunb0c  于 2023-06-05  发布在  React
关注(0)|答案(1)|浏览(119)

我正在创建一个单页的React网站,我有一个标题导航,其中有链接到不同的部分。如果我点击一个部分,它会链接到一个锚(在像#section-1这样的URL中),并将类active添加到导航中的元素。
现在我还希望当我从section-1滚动到section-2时,它将URL中的锚更新为section-2,并从第一个链接中删除类active并将其添加到第二个链接中。我如何才能做到这一点?
对于导航中的链接元素,我使用react-bootstrap 2.5.0中的Nav.Link

zaq34kh6

zaq34kh61#

要在单页React网站中实现此功能,您可以按照以下步骤操作:
1.设置标题导航组件,并将其链接到不同的部分。每个链接都应该有一个onClick事件处理程序来处理滚动和类更新。
1.在组件中创建一个状态变量以跟踪活动节,并使用默认节对其进行初始化。
1.为每个链接实现onClick事件处理程序。在事件处理程序中,更新状态中的活动节并滚动到相应的节。
1.向组件添加滚动事件侦听器以跟踪滚动位置并相应地更新活动部分。
1.在滚动事件侦听器中,计算滚动位置并确定当前查看的部分。
1.根据滚动位置更新状态中的活动部分。
1.添加一个useEffect钩子来监听活动节状态变量中的更改,并相应地更新URL锚。
1.添加一个useEffect钩子来监听URL锚中的更改并相应地更新活动部分。
下面是一个示例实现,可以帮助您开始:

import React, { useState, useEffect } from 'react';

const Header = () => {
  const [activeSection, setActiveSection] = useState('section-1');

  const handleLinkClick = (section) => {
    setActiveSection(section);
    scrollToSection(section);
  };

  const scrollToSection = (section) => {
    const element = document.getElementById(section);
    element.scrollIntoView({ behavior: 'smooth' });
  };

  useEffect(() => {
    const handleScroll = () => {
      const scrollPosition = window.scrollY;
      const sections = document.querySelectorAll('section');
      
      sections.forEach((section) => {
        const sectionTop = section.offsetTop;
        const sectionHeight = section.offsetHeight;

        if (
          scrollPosition >= sectionTop - 50 && // Adjust the offset as needed
          scrollPosition < sectionTop + sectionHeight - 50 // Adjust the offset as needed
        ) {
          setActiveSection(section.id);
        }
      });
    };

    window.addEventListener('scroll', handleScroll);
    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  useEffect(() => {
    const handleUrlAnchorChange = () => {
      const sectionFromUrl = window.location.hash.substr(1);
      setActiveSection(sectionFromUrl);
    };

    window.addEventListener('hashchange', handleUrlAnchorChange);
    return () => {
      window.removeEventListener('hashchange', handleUrlAnchorChange);
    };
  }, []);

  useEffect(() => {
    window.location.hash = activeSection;
  }, [activeSection]);

  return (
    <nav>
      <ul>
        <li>
          <a
            href="#section-1"
            className={activeSection === 'section-1' ? 'active' : ''}
            onClick={() => handleLinkClick('section-1')}
          >
            Section 1
          </a>
        </li>
        <li>
          <a
            href="#section-2"
            className={activeSection === 'section-2' ? 'active' : ''}
            onClick={() => handleLinkClick('section-2')}
          >
            Section 2
          </a>
        </li>
        {/* Add more links for other sections */}
      </ul>
    </nav>
  );
};

export default Header;

在该示例中,使用activeSection状态变量来跟踪活动区段。当单击链接时,将调用handleLinkClick函数,更新活动部分并滚动到相应部分。滚动事件侦听器计算滚动位置并相应地更新活动部分。使用活动的

相关问题