【发布时间】:2021-09-10 23:08:36
【问题描述】:
当您滚动到列表中的某个位置并按“空格”时,新元素将添加到列表中。代码意图是保持与用户按下“空格”之前相同的滚动视图。加载项目并在几毫秒内,滚动视图位于新前置项目的顶部,然后滚动到保存的先前滚动视图。我想立即制作它,而不会出现让用户烦恼的毫秒延迟。
能买到吗?
代码:
import React, { useState, useEffect, useRef } from "react";
import "./styles.css";
export default function App() {
const listRefs = useRef({});
const scrollRef = useRef();
const oldListHeight = useRef();
const generateId = (length) => {
let result = "";
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
};
const generateList = () => {
const html = [];
for (let i = 0; i < Math.floor(Math.random() * 30) + 20; i++) {
const id = generateId(15);
listRefs.current[id] = React.createRef();
html.push(
<li ref={listRefs[id]} key={id}>
{id}
</li>
);
}
return html;
};
const [htmlList, setHtmlList] = useState(generateList());
useEffect(() => {
setTimeout(() => {
const listHeightDiff =
scrollRef.current.scrollHeight - oldListHeight.current;
scrollRef.current.scrollTo({
top: scrollRef.current.scrollTop + listHeightDiff
});
}, 0);
}, [htmlList]);
useEffect(() => {
window.addEventListener("keydown", handleKeyDown, false);
return () => {
window.removeEventListener("keydown", handleKeyDown, false);
};
}, []);
const handleKeyDown = (e) => {
if (e.key === " ") {
oldListHeight.current = scrollRef.current.scrollHeight;
setHtmlList((htmlList) => [generateList(), ...htmlList]);
}
};
return (
<div className="App">
<div ref={scrollRef} className="wrapper">
<ul>{htmlList}</ul>
</div>
</div>
);
}
游乐场:
https://codesandbox.io/s/affectionate-antonelli-wkvvd?file=/src/App.js
【问题讨论】:
-
你的问题不是很清楚。您是想说
htmlList一次又一次地加载所有内容,并在您不断添加越来越多的内容时造成一点延迟? -
进入 Playground,按几次“空格键”创建一个大的可滚动列表。然后滚动到一个位置并按“空格键”。您会看到新列表收费的延迟,然后滚动到最后一个视图。这不是立即的,我希望在没有那个小延迟的情况下获得相同的结果。
-
说实话,它就像一个魅力。即使在您的 CodeSandbox 中尝试,我也无法重现您遇到的问题
-
我制作了一个视频来向您展示这个问题。检查添加新列表时的小延迟:files.fm/f/8wd9k4h38
-
检查更新的代码和答案。
标签: javascript reactjs scroll