如何移动滚动Y轴不管设备的高度在reactjs?



我制作了一个组件,它有4个垂直部分

如果我点击顶部的菜单我想让滚动条移动到每个部分

例如,

  • 点击菜单1 ->第一节
  • 点击菜单2 ->第二节
  • 点击菜单3 ->第三节

对于这个,我通过帧运动的useScroll得到每个section的Y值。

如果我点击某个菜单,我让window.location移动到那个Y值

但问题是,如果我在手机上看这个主页,而不是桌面,因为设备高度改变,sections的Y值也会改变。

所以即使它移动到设备1第2部分的Y值,在设备e2中,滚动指向不同的部分

那么如何使这个功能不管不同的设备高度?

我还尝试使用Route path通过不同的路线将每个部分分开。

但是我无法在一页中区分组件的路由路径。

const { scrollY } = useScroll();
const [ychange, setYchange] = useState(0);
useEffect(() => {
scrollY.onChange(() => {

setYchange(scrollY.get());

});
}, [scrollY]);
<NavItem
onClick={() => {
navigate("/");
setTimeout(() => {
window.scrollTo({ top: 5235, behavior: "smooth" });
});
}}
>
<AppText page={page} ychange={ychange} location={location}>
앱 소개
</AppText>
{page === "app" ||
(location === "/" && ychange >= 5234 && ychange < 10336) ? (
<NavBottom />
) : null}
</NavItem>

似乎element.scrollIntoView()可能是一个很好的适合,如果这是用例:

  • 点击菜单1 ->第一节
  • 点击菜单2 ->第二节
  • 点击菜单3 ->第三节

一个可能的实现是为每个sectionuseRef滚动到一个引用,并在引用的元素上调用scrollIntoView()

关于element.scrollIntoView()的更多信息

可选:当滚动到时,从元素顶部开始的偏移区域可以在样式中使用scroll-margin-top指定。

关于scroll-margin-top的更多信息

下面是实现该功能的一个基本示例。为了方便,它在代码片段中运行,在整个页面中查看时效果更好。

不确定这种方法是否能在实际项目中很好地工作,因为发布的代码是部分的,但希望这仍然可以作为参考。

const { useRef } = React;
const App = () => {
const sectionsRef = useRef([]);
const handleScrollTo = (index) => {
if (!sectionsRef.current[index]) return;
sectionsRef.current[index].scrollIntoView({ behavior: "smooth" });
};
return (
<div className="App">
<nav>
{[1, 2, 3, 4].map((item, index) => (
<button key={item} onClick={()=>handleScrollTo(index)}>{`Section ${item}`}</button>
))}
</nav>
{[1, 2, 3, 4].map((item, index) => (
<section key={item} ref={(element) => (sectionsRef.current[index] = element)}>
<h3>{`This is section ${item}`}</h3>
</section>
))}
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root")).render(
<App />
);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
nav,
section,
button {
display: flex;
justify-content: center;
align-items: center;
}
nav {
position: sticky;
top: 0;
padding: 6px;
width: 100%;
height: 50px;
background-color: lightpink;
gap: 12px;
}
button {
padding: 6px;
}
section {
scroll-margin-top: 50px;
width: 100%;
min-height: 100vh;
background-color: lightgreen;
}
section:nth-of-type(1) {
background-color: lightblue;
}
section:nth-of-type(2) {
background-color: lightgreen;
}
section:nth-of-type(3) {
background-color: purple;
}
section:nth-of-type(4) {
background-color: gold;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

最新更新