gpt4 book ai didi

html - 将 div 的当前滚动保存到本地存储,React

转载 作者:行者123 更新时间:2023-12-03 08:10:48 26 4
gpt4 key购买 nike

我见过很多关于这个主题的问题,但似乎没有一个人按照我的方式解决这个问题。它们通常涉及窗口滚动。我有一个 div,其中的项目可能会溢出,并且我想记住用户留下的滚动条。我将其保存在本地存储中,但无法获得正确的滚动位置。 (项目数以百计)

const ItemHolder = ({
shouldScroll, // this indicates whether or not we should load the previous scroll from the storage
searchParams,
}: ItemHolderProps) => {
const [items, setItems] = useImmer<Item[]>([]);

const scrollRef = useRef<HTMLDivElement>(null);


useEffect(() => { // HERE WE SHOULD GET THE SCROLL VALUE WHEN UNMOUNTING
const scroll = scrollRef.current; // this is because we don't have access to ref.current in unmount

return () => {
if (scroll) {
// doesn't work
const winScroll = scroll.scrollTop;
const height = scroll.scrollHeight - scroll.clientHeight;

const scrolled = winScroll / height;

localStorage.setItem("scroll", String(scrolled));
}
};
}, []);

useEffect(() => {
const scroll = scrollRef.current;
const scrollAmountStorage = localStorage.getItem("scroll");

let scrollTop = 0;
if (scrollAmountStorage) {
scrollTop = Number(scrollAmountStorage);
}

if (shouldScroll && scroll) {
console.log("Scroll top : ", scrollTop);
scroll.scrollTo({ top: scrollTop });
}
}, [shouldScroll]);

return (
<div
// onScroll={(e) => {
// console.log(e);
// }}
ref={scrollRef}
className="grid grid-cols-2 mx-auto p-2 gap-3 overflow-x-auto h-full"
>
{items.map((i) => (
<Item key={i.id} />
))}
</div>
);
};

基本上让我困惑的是,没有直观和直接的方法来获取当前滚动,然后再次应用它。我发现的所有 SO 答案都使用了 windows.height 等此类计算。

最佳答案

我为你做了一个非常简单的例子 here

我们可以使用 onScroll 事件来处理和获取 div 的当前滚动位置,但我们不想每次都更新状态,因此我们可以创建一个函数来消除滚动事件的抖动(这样当用户停止滚动时它将更新状态) )

function useDebounce(delay = 500) {
const [data, setData] = useState(null);
const [dataQuery, setDataQuery] = useState(null);

useEffect(() => {
const delayFn = setTimeout(() => setData(dataQuery), delay);
return () => clearTimeout(delayFn);
}, [dataQuery, delay]);

return [data, setDataQuery];
}

我们将这样使用它:

const [scrollPosition, setScrollPosition] = useDebounce();

在我们要存储滚动位置的div上:

<div
ref={scrollRef}
onScroll={({ target }) => setScrollPosition(target.scrollTop)}
/>

然后我们将创建一个 useEffect 来在 scrollPosition 更改时存储值:

useEffect(() => {
if (scrollPosition) localStorage.setItem("scrollPosition", scrollPosition);
}, [scrollPosition]);

最后我们将为初始渲染创建 useEffect 来更改滚动位置;

useEffect(() => {
let scrollPosition = localStorage.getItem("scrollPosition");
if (scrollPosition) scrollRef.current.scrollTop = scrollPosition;
}, []);

整体代码应该如下所示;

import { useEffect, useRef, useState } from "react";

function useDebounce(delay = 500) {
const [data, setData] = useState(null);
const [dataQuery, setDataQuery] = useState(null);

useEffect(() => {
const delayFn = setTimeout(() => setData(dataQuery), delay);
return () => clearTimeout(delayFn);
}, [dataQuery, delay]);

return [data, setDataQuery];
}

export default function App() {
const scrollRef = useRef(null);
const [scrollPosition, setScrollPosition] = useDebounce();

useEffect(() => {
let scrollPosition = localStorage.getItem("scrollPosition");
if (scrollPosition) scrollRef.current.scrollTop = scrollPosition;
}, []);

useEffect(() => {
if (scrollPosition) localStorage.setItem("scrollPosition", scrollPosition);
}, [scrollPosition]);

return (
<div className="App">
<div
ref={scrollRef}
style={{ width: "200px", height: "200px", overflow: "auto" }}
onScroll={({ target }) => {
setScrollPosition(target.scrollTop);
}}
>
<div style={{ width: "100%", height: "15000px" }} />
</div>
</div>
);
}

关于html - 将 div 的当前滚动保存到本地存储,React,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70894148/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com