javascript 在多页面React应用程序中,组件从一个页面的结尾滚动到下一个页面的开头时出现问题

ix0qys7i  于 2023-10-14  发布在  Java
关注(0)|答案(1)|浏览(86)

正如标题所描述的,我目前正在开发一个多页面的React应用程序,我希望用户能够从一个页面滚动到另一个页面,以及使用导航菜单来浏览网站。这样,如果用户想要导航到特定页面,他们可以使用菜单,但他们也可以逐页浏览网站。我想一个提示,当用户到达一个页面的末尾,说明“滚动了解更多”,然后如果一个单独的滚动事件被检测到,然后应用程序导航到下一页。
我目前有一些功能,但不是我想要的,这是下面的代码:

import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { FaArrowDown } from "react-icons/fa";

import classes from "./ScrollingNav.module.css";

function ScrollingNav({ pages, children }) {
  const navigate = useNavigate();
  const [showPrompt, setShowPrompt] = useState(false);
  const [atBottom, setAtBottom] = useState(false);
  const [currentIndex, setCurrentIndex] = useState(0);

  useEffect(() => {
    const handleScroll = () => {
      const windowHeight = window.innerHeight;
      const scrollPosition = window.scrollY;
      const contentHeight = document.documentElement.scrollHeight;

      const scrollBuffer = 100;
      // const minDistance = 200;

      if (
        contentHeight - (scrollPosition + windowHeight) < scrollBuffer &&
        // contentHeight- (scrollPosition + windowHeight) > minDistance
        !atBottom
      ) {
        setShowPrompt(true);
      } else {
        setShowPrompt(false);
      }

      if (contentHeight - (scrollPosition + windowHeight) === 0) {
        setAtBottom(true);
      }
    };

    const handleNavigate = () => {
      if (atBottom) {
        if (currentIndex + 1 < pages.length) {
          setCurrentIndex(currentIndex + 1);
          navigate(pages[currentIndex + 1]);
        }
      }
    };

    window.addEventListener("scroll", handleScroll);
    window.addEventListener("scroll", handleNavigate);

    return () => {
      window.removeEventListener("scroll", handleScroll);
      window.removeEventListener("scroll", handleNavigate);
    };
  }, [currentIndex, navigate, pages, atBottom]);

  return (
    <div>
      {children}
      {showPrompt && (
        <div>
          Scroll to Learn More
          <FaArrowDown size={50} />
        </div>
      )}
    </div>
  );
}

export default ScrollingNav;

我有一个组件,它接收一个列表的路线和一个儿童 prop 。页面列表用于索引下一页。当前代码在用户到达页面末尾时呈现提示,但仅在用户从底部向上滚动时进行导航。我认为这是由于if语句:

if (contentHeight - (scrollPosition + windowHeight) === 0) {
        setAtBottom(true);
      }

问题是,如果我将值与0以外的任何值进行比较,例如:

if (contentHeight - (scrollPosition + windowHeight) < 5) {
        setAtBottom(true);
      }

则当用户到达底部并且页脚甚至还未完全可见时,应用立即滚动。页眉和页脚在app.js中呈现在页面内容之外,这样它们就出现在每个页面的顶部和底部,如下所示:

function App() {
    return (
        <UserContextProvider>
            <div className="App">
                <Header />
                <Routes>
                    <Route path="/" element={<HomePage />} /}
                    ... other routes
                </Routes>
                <Footer />
            </div>
        </UserContextProvider>
    );
}

我不确定这样设置的页面是否会引起任何问题,所以我想我会把它包括在内。
有可能是一个完全不同的方式去实现我想要的结果,所以我愿意接受任何建议。有没有一种方法可以修改我的代码,使其在到达页面底部后隔离一个单独的向下滚动事件,从而导致应用导航到下一页?

enxuqcxy

enxuqcxy1#

这将是值得你的时候阅读DOM元素滚动.如何使用React useRef来处理滚动事件?
什么是atBottom和scrollBuffer?
我不知道if语句在做什么。我觉得if语句很简洁。
也许,当用户到达页面上的最后一个dom元素或页面上的特定滚动深度时,可以使用事件侦听器。想象一下无限滚动是如何工作的,它会将下一批页面排队。
我想用更少的代码就可以实现这一点。
获取dom的scroll事件获取dom的height(maybe this dynamically updates for different viewport or window resize)获取主选择器事件监听器如果用户到达一个滚动位置或者dom元素出现在viewport(like the footer)触发下一页
检查...
https://react.dev/reference/react/useRef#manipulating-the-dom-with-a-ref
https://infinite-scroll.com/
检查此项目是否处理滚动事件
https://larsjung.de/jquery-fracs/
http://imakewebthings.com/waypoints/guides/getting-started/

相关问题