From 4febbb4cd6ad35f8a771f6d1090c20c7cce507b2 Mon Sep 17 00:00:00 2001 From: AlejandroAkbal <37181533+AlejandroAkbal@users.noreply.github.com> Date: Sat, 14 Mar 2026 12:28:19 -0700 Subject: [PATCH] fix: hide the post navbar while scrolling --- components/layout/navigation/Navbar.vue | 84 ++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/components/layout/navigation/Navbar.vue b/components/layout/navigation/Navbar.vue index 76837e90..b91b6c54 100644 --- a/components/layout/navigation/Navbar.vue +++ b/components/layout/navigation/Navbar.vue @@ -26,29 +26,95 @@ ) const isOnTop = ref(true) + const isNavbarVisible = ref(true) + const lastScrollY = ref(0) - function onIntersectionObserver(entries: IntersectionObserverEntry[]) { - const [entry] = entries + const SCROLL_DELTA_THRESHOLD = 12 + const TOP_VISIBILITY_THRESHOLD = 8 - if (entry.isIntersecting) { - isOnTop.value = true - } else { - isOnTop.value = false + let scrollRafId: number | null = null + + function onIntersectionObserver(entries: IntersectionObserverEntry[], _observer: IntersectionObserver) { + const entry = entries[0] + + if (!entry) { + return + } + + isOnTop.value = entry.isIntersecting + } + + function onWindowScroll() { + if (!isPostsPage.value || scrollRafId !== null) { + return } + + scrollRafId = window.requestAnimationFrame(() => { + const currentScrollY = window.scrollY + + if (currentScrollY <= TOP_VISIBILITY_THRESHOLD) { + isNavbarVisible.value = true + lastScrollY.value = currentScrollY + scrollRafId = null + + return + } + + const deltaY = currentScrollY - lastScrollY.value + + if (Math.abs(deltaY) >= SCROLL_DELTA_THRESHOLD) { + isNavbarVisible.value = deltaY < 0 + lastScrollY.value = currentScrollY + } + + scrollRafId = null + }) } + + watch( + isPostsPage, + (value) => { + if (!import.meta.client) { + return + } + + if (!value) { + isNavbarVisible.value = true + } + + lastScrollY.value = window.scrollY + }, + { immediate: true } + ) + + onMounted(() => { + lastScrollY.value = window.scrollY + window.addEventListener('scroll', onWindowScroll, { passive: true }) + }) + + onBeforeUnmount(() => { + window.removeEventListener('scroll', onWindowScroll) + + if (scrollRafId !== null) { + window.cancelAnimationFrame(scrollRafId) + scrollRafId = null + } + })