diff --git a/apps/dm/app/(with-layout)/example/page.tsx b/apps/dm/app/(with-layout)/example/page.tsx
index b32b3346e..94e908d81 100644
--- a/apps/dm/app/(with-layout)/example/page.tsx
+++ b/apps/dm/app/(with-layout)/example/page.tsx
@@ -1,3 +1,6 @@
+/**
+ * 물 재이용 사례
+ */
import SubPageHeader from "@/components/SubPageHeader";
import BusinessSubNav, { type BusinessSubNavMenu } from "@/components/BusinessSubNav";
diff --git a/apps/dm/app/(with-layout)/status/_components/SewageStatusSection.tsx b/apps/dm/app/(with-layout)/status/_components/SewageStatusSection.tsx
index cd660a929..f7eb49a84 100644
--- a/apps/dm/app/(with-layout)/status/_components/SewageStatusSection.tsx
+++ b/apps/dm/app/(with-layout)/status/_components/SewageStatusSection.tsx
@@ -287,7 +287,7 @@ export default function SewageStatusSection() {
const isSubItem = type === "red-item" || type === "blue-item";
if (index === 0) {
- console.log(header.id, value);
+ // console.log(header.id, value);
return (
{isSubItem ? (
diff --git a/apps/dm/app/(with-layout)/status/page.tsx b/apps/dm/app/(with-layout)/status/page.tsx
index b18662c06..8bed3d04f 100644
--- a/apps/dm/app/(with-layout)/status/page.tsx
+++ b/apps/dm/app/(with-layout)/status/page.tsx
@@ -58,7 +58,7 @@ const menus: BusinessSubNavMenu[] = [
},
{
id: "status-treated-usage",
- label: "연도별 하수처리수 재이용 현황",
+ label: "용도별 하수처리수 재이용 현황",
},
{
id: "status-treated-facility",
diff --git a/apps/dm/components/BusinessSubNav.tsx b/apps/dm/components/BusinessSubNav.tsx
index 6b4246412..d8753b5dd 100644
--- a/apps/dm/components/BusinessSubNav.tsx
+++ b/apps/dm/components/BusinessSubNav.tsx
@@ -1,3 +1,6 @@
+/**
+ * 우측 메뉴
+ */
"use client";
import Link from "next/link";
@@ -47,44 +50,67 @@ export default function BusinessSubNav({
setOpenMenus(initialOpenState);
}, [menus]);
- useEffect(() => {
- if (!allSections.length) return;
+useEffect(() => {
+ if (!allSections.length) return;
- const observer = new IntersectionObserver(
- (entries) => {
- const visible = entries
- .filter((entry) => entry.isIntersecting)
- .sort((a, b) => b.intersectionRatio - a.intersectionRatio);
+ const targets = allSections
+ .map((section) => document.getElementById(section.id))
+ .filter(Boolean) as HTMLElement[];
- if (visible[0]) {
- setActiveId(visible[0].target.id);
- }
- },
- {
- rootMargin: `-${offsetTop}px 0px -55% 0px`,
- threshold: [0.2, 0.35, 0.5, 0.7],
+ if (!targets.length) return;
+
+ let rafId = 0;
+
+ const updateActiveSection = () => {
+ const baseLine = offsetTop + 500;
+ let nextActiveId = targets[0]?.id ?? "";
+
+ for (const el of targets) {
+ const { top } = el.getBoundingClientRect();
+ if (top <= baseLine) {
+ nextActiveId = el.id;
+ continue;
}
- );
- const targets = allSections
- .map((section) => document.getElementById(section.id))
- .filter(Boolean) as HTMLElement[];
+ break;
+ }
- targets.forEach((el) => observer.observe(el));
+ setActiveId((prev) => (prev === nextActiveId ? prev : nextActiveId));
+ };
- const hash = window.location.hash.replace("#", "");
- const initialActive =
- allSections.find((section) => section.id === hash)?.id ??
- allSections[0]?.id ??
- "";
+ const requestUpdate = () => {
+ if (rafId) return;
- setActiveId(initialActive);
+ rafId = window.requestAnimationFrame(() => { // 예약번호 반환
+ updateActiveSection();
+ rafId = 0;
+ });
+ };
- return () => observer.disconnect();
- }, [allSections, offsetTop]);
+ const hash = window.location.hash.replace("#", "");
+ const initialActive =
+ allSections.find((section) => section.id === hash)?.id ??
+ allSections[0]?.id ??
+ "";
- useEffect(() => {
- if (!activeId) return;
+ setActiveId(initialActive);
+ updateActiveSection();
+
+ window.addEventListener("scroll", requestUpdate, { passive: true });
+ window.addEventListener("resize", requestUpdate);
+
+ return () => {
+ window.removeEventListener("scroll", requestUpdate);
+ window.removeEventListener("resize", requestUpdate);
+
+ if (rafId) {
+ window.cancelAnimationFrame(rafId);
+ }
+ };
+}, [allSections, offsetTop]);
+
+ useEffect(() => {
+ if (!activeId) return;
const parentMenu = menus.find((menu) =>
(menu.sections ?? []).some((section) => section.id === activeId)
@@ -93,13 +119,13 @@ export default function BusinessSubNav({
if (!parentMenu) return;
setOpenMenus(() => {
- const nextOpenState: Record = {};
+ const nextOpenState: Record = {};
- menus.forEach((menu) => {
+ menus.forEach((menu) => {
nextOpenState[menu.key] = menu.key === parentMenu.key;
- });
+ });
- return nextOpenState;
+ return nextOpenState;
});
}, [activeId, menus]);
|