正如标题所描述的,我目前正在开发一个多页面的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>
);
}
我不确定这样设置的页面是否会引起任何问题,所以我想我会把它包括在内。
有可能是一个完全不同的方式去实现我想要的结果,所以我愿意接受任何建议。有没有一种方法可以修改我的代码,使其在到达页面底部后隔离一个单独的向下滚动事件,从而导致应用导航到下一页?
1条答案
按热度按时间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/