62 lines
1.6 KiB
JavaScript
62 lines
1.6 KiB
JavaScript
"use client";
|
|
import { useEffect, useCallback, useState } from "react";
|
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
import { Suspense } from "react";
|
|
|
|
const ScrollHandlerInner = () => {
|
|
const pathname = usePathname();
|
|
const searchParams = useSearchParams();
|
|
|
|
const scrollToHash = useCallback(() => {
|
|
const hash = window.location.hash;
|
|
if (hash) {
|
|
const elementId = hash.substring(1);
|
|
const element = document.getElementById(elementId);
|
|
|
|
if (element) {
|
|
const yOffset = -200;
|
|
setTimeout(() => {
|
|
const y = element.getBoundingClientRect().top + window.scrollY + yOffset;
|
|
window.scrollTo({
|
|
top: y,
|
|
behavior: "smooth",
|
|
});
|
|
}, 100);
|
|
}
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (window.location.hash) {
|
|
scrollToHash();
|
|
}
|
|
}, [pathname, searchParams, scrollToHash]);
|
|
|
|
useEffect(() => {
|
|
window.addEventListener("hashchange", scrollToHash);
|
|
return () => window.removeEventListener("hashchange", scrollToHash);
|
|
}, [scrollToHash]);
|
|
|
|
return null;
|
|
};
|
|
|
|
const ClientScrollHandler = () => {
|
|
const [isMounted, setIsMounted] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setIsMounted(true);
|
|
}, []);
|
|
|
|
if (!isMounted) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Suspense fallback={null}>
|
|
<ScrollHandlerInner />
|
|
</Suspense>
|
|
);
|
|
};
|
|
|
|
export default ClientScrollHandler;
|