我在一个网站上看到了这种很酷的效果,滚动到达末尾又从头开始无缝地开始。如果您向后滚动,它将转到着陆部分。
我很好奇并尝试重现这种效果,但没有成功。
我做了一个组件
Scrollable
接受儿童。并让孩子们充满了div和图像。
我所做的是在可滚动组件内部使用 useRef 将子项附加到可滚动组件,并在滚动到达底部时删除顶部的组件。使用公式
element.scrollHeight - element.scrollTop === element.clientHeight
我的做法有什么问题吗?
interface ScrollableProps {
heading: string;
children?: React.ReactNode;
}
const Scrollable = ({ heading, children }: ScrollableProps) => {
const scrollRef = React.useRef<HTMLDivElement>(null);
const contentRef = React.useRef<HTMLDivElement>(null);
useEffect(() => {
const handleScrollForScrollable = () => {
console.log("scrolling");
const { scrollTop, scrollHeight, clientHeight } = scrollRef.current!;
console.log("here ", scrollTop, scrollHeight, clientHeight);
if (scrollTop + clientHeight >= scrollHeight) {
console.log("Reached end of scrollable");
contentRef.current!.appendChild(
contentRef.current!.firstElementChild!.cloneNode(true)
);
}
};
scrollRef.current?.addEventListener("scroll", handleScrollForScrollable);
return () => {
scrollRef.current?.removeEventListener(
"scroll",
handleScrollForScrollable
);
};
}, []);
return (
<div ref={scrollRef} className="scrollable">
<StickyNavBar heading={heading}></StickyNavBar>
<div ref={contentRef} className="scrollable-contents">
{children}
</div>
</div>
);
};
编辑:这里是原始网站的链接:https://www.zegzulka.com/向下滚动以查看无限滚动效果。 (仅适用于网页版)
Zegzulka 页面似乎重复内容并使用
transform()
滚动所需视图以显示。
使用 React,你可以用这种方式做到这一点:
const ScrollDiv = ({ children }) => {
const ref = useRef(null);
const [y, setY] = useState(0);
return (
<div
style={{ overflow: "hidden" }}
onWheel={(e) => {
const limit = ref.current.getBoundingClientRect().height / 2;
let newY = y + e.deltaY / 10;
if (newY > limit) newY -= limit;
if (newY < 0) newY += limit;
setY(newY);
}}
>
<div
ref={ref}
style={{
display: "grid",
overflow: "hidden",
transform: `translateY(${-y}px)`,
}}
>
{children}
{children}
</div>
</div>
);
};
注意
{children}
必须是两倍。这样,第一个元素会在最后一个元素之后“再次出现”。