English 中文(简体)
Problem with component to scroll from end of one page to start of next within multipage react app
原标题:

As the title describes, I am currently working on a multipage react app and I would like for users to be able to scroll from page to page as well as use a navmenu to go through the site. This way if a user wants to navigate to a specific page they can use the menu but they can also go through the site page by page. I would like a prompt to come up when the user arrives at the end of a page stating to "scroll to learn more" and then if a separate scrolling event is detected, then the app navigates to the next page.

I currently have something that functions but not as I would like it to which is the following code:

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;

I have the component which receives a list of routes and a children prop. The list of pages is for indexing which page is next. The current code renders the prompt when the user arrives at the end of the page but only navigates if the user scrolls upwards from the bottom. I believe this to be due to the if statement:

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

The issue is if I set the value being compared with the anything other than 0, for example:

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

then the app instantly scrolls when the user reaches the bottom and the footer is not even completely visible yet. The header and footer and rendered outside of the page content in app.js so that they are present at the top and bottom of every page like this:

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

I am not sure if the pages being set up like this is causing any issues so I figured I would include this for context.

There could be an entirely different way to go about achieving my desired outcome so I am open to any suggestions. Is there a way to modify my code such that it isolates a separate downward scrolling event after the bottom of the page is reached which causes the app to navigate to the next page?

问题回答

暂无回答




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签