@@ -34,6 +34,32 @@ const languages: Record<Lang, string> = {
3434 ja: ' 🇯🇵 日本語' ,
3535};
3636
37+ function normalizePath(path : string ) {
38+ if (! path ) return ' /' ;
39+ return path .endsWith (' /' ) ? path : ` ${path }/ ` ;
40+ }
41+
42+ const homePath = computed (() => ` /${props .lang }/ ` );
43+ const isHome = computed (() => normalizePath (props .currentPath ) === homePath .value );
44+ const scrollTargetKey = ' rushdb-scroll-target' ;
45+
46+ function sectionHref(id : string ) {
47+ return isHome .value ? ` #${id } ` : homePath .value ;
48+ }
49+
50+ function navigateToSection(id : string ) {
51+ if (isHome .value ) {
52+ const targetEl = document .getElementById (id );
53+ if (targetEl ) {
54+ targetEl .scrollIntoView ({ behavior: ' smooth' , block: ' start' });
55+ }
56+ return ;
57+ }
58+
59+ sessionStorage .setItem (scrollTargetKey , id );
60+ window .location .href = homePath .value ;
61+ }
62+
3763let navHighlightObserver: IntersectionObserver | null = null ;
3864
3965function toggleLanguageSwitcher() {
@@ -73,6 +99,12 @@ function scrollToTop() {
7399 window .scrollTo ({ top: 0 , behavior: ' smooth' });
74100}
75101
102+ function onLogoClick(event : MouseEvent ) {
103+ if (! isHome .value ) return ;
104+ event .preventDefault ();
105+ scrollToTop ();
106+ }
107+
76108function updateNavbarBg() {
77109 navbarBg .value = window .scrollY > 100 ? ' rgba(5, 7, 18, 0.82)' : ' rgba(5, 7, 18, 0.72)' ;
78110}
@@ -93,6 +125,17 @@ function onDocumentClick(event: MouseEvent) {
93125 closeNavMenu ();
94126 }
95127
128+ const sectionAnchor = target .closest <HTMLAnchorElement >(' a[data-section]' );
129+ if (sectionAnchor ) {
130+ const sectionId = sectionAnchor .dataset .section ;
131+ if (! sectionId ) return ;
132+
133+ event .preventDefault ();
134+ closeNavMenu ();
135+ navigateToSection (sectionId );
136+ return ;
137+ }
138+
96139 const anchor = target .closest <HTMLAnchorElement >(' a[href^="#"]:not(.nav-logo)' );
97140 if (! anchor ) return ;
98141
@@ -150,7 +193,7 @@ onUnmounted(() => {
150193<template >
151194 <nav class =" navbar" :class =" { 'menu-open': isMenuOpen }" :style =" { background: navbarBg }" role =" navigation" :aria-label =" t('a11y.mainNavigation')" >
152195 <div class =" nav-content" >
153- <a href =" # " class =" nav-logo" @click.prevent = " scrollToTop " >
196+ <a : href =" homePath " class =" nav-logo" @click = " onLogoClick " >
154197 <img src =" /RushDB.png" alt =" RushDB Logo" class =" nav-logo-img" />
155198 <span >&ensp ; RushDB</span >
156199 </a >
@@ -159,16 +202,22 @@ onUnmounted(() => {
159202 <div class =" nav-actions nav-desktop" >
160203 <ul class =" nav-links" >
161204 <li >
162- <a href =" # about" :class =" { active: activeSection === 'about' }" >{{ t('nav.about') }}</a >
205+ <a : href =" sectionHref('about') " data-section = " about" :class =" { active: activeSection === 'about' }" >{{ t('nav.about') }}</a >
163206 </li >
164207 <li >
165- <a href =" #achievements" :class =" { active: activeSection === 'achievements' }" >{{ t('nav.achievements') }}</a >
208+ <a
209+ :href =" sectionHref('achievements')"
210+ data-section =" achievements"
211+ :class =" { active: activeSection === 'achievements' }"
212+ >
213+ {{ t('nav.achievements') }}
214+ </a >
166215 </li >
167216 <li >
168- <a href =" # projects" :class =" { active: activeSection === 'projects' }" >{{ t('nav.projects') }}</a >
217+ <a : href =" sectionHref('projects') " data-section = " projects" :class =" { active: activeSection === 'projects' }" >{{ t('nav.projects') }}</a >
169218 </li >
170219 <li >
171- <a href =" # members" :class =" { active: activeSection === 'members' }" >{{ t('nav.members') }}</a >
220+ <a : href =" sectionHref('members') " data-section = " members" :class =" { active: activeSection === 'members' }" >{{ t('nav.members') }}</a >
172221 </li >
173222 <li >
174223 <a :href =" `/${lang}/blog/`" class =" nav-blog-link" >{{ t('nav.blog') }}</a >
@@ -204,16 +253,29 @@ onUnmounted(() => {
204253 <div class =" nav-mobile-menu" :class =" { open: isMenuOpen }" >
205254 <ul class =" nav-mobile-links" >
206255 <li >
207- <a href =" #about" :class =" { active: activeSection === 'about' }" @click =" closeNavMenu" >{{ t('nav.about') }}</a >
256+ <a :href =" sectionHref('about')" data-section =" about" :class =" { active: activeSection === 'about' }" @click =" closeNavMenu" >
257+ {{ t('nav.about') }}
258+ </a >
208259 </li >
209260 <li >
210- <a href =" #achievements" :class =" { active: activeSection === 'achievements' }" @click =" closeNavMenu" >{{ t('nav.achievements') }}</a >
261+ <a
262+ :href =" sectionHref('achievements')"
263+ data-section =" achievements"
264+ :class =" { active: activeSection === 'achievements' }"
265+ @click =" closeNavMenu"
266+ >
267+ {{ t('nav.achievements') }}
268+ </a >
211269 </li >
212270 <li >
213- <a href =" #projects" :class =" { active: activeSection === 'projects' }" @click =" closeNavMenu" >{{ t('nav.projects') }}</a >
271+ <a :href =" sectionHref('projects')" data-section =" projects" :class =" { active: activeSection === 'projects' }" @click =" closeNavMenu" >
272+ {{ t('nav.projects') }}
273+ </a >
214274 </li >
215275 <li >
216- <a href =" #members" :class =" { active: activeSection === 'members' }" @click =" closeNavMenu" >{{ t('nav.members') }}</a >
276+ <a :href =" sectionHref('members')" data-section =" members" :class =" { active: activeSection === 'members' }" @click =" closeNavMenu" >
277+ {{ t('nav.members') }}
278+ </a >
217279 </li >
218280 <li >
219281 <a :href =" `/${lang}/blog/`" class =" nav-blog-link" >{{ t('nav.blog') }}</a >
0 commit comments