From 8e9bf67d9a755703837040209990b178bb4c3c68 Mon Sep 17 00:00:00 2001 From: Volpeon Date: Wed, 3 Jan 2024 16:23:02 +0100 Subject: [PATCH] Restore scroll position on navigation --- packages/frontend/src/nirax.ts | 4 ++-- packages/frontend/src/router.ts | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/nirax.ts b/packages/frontend/src/nirax.ts index 9755bdcb1..9564a754f 100644 --- a/packages/frontend/src/nirax.ts +++ b/packages/frontend/src/nirax.ts @@ -78,7 +78,7 @@ export class Router extends EventEmitter<{ public current: Resolved; public currentRef: ShallowRef = shallowRef(); public currentRoute: ShallowRef = shallowRef(); - private currentPath: string; + private currentPath = ''; private isLoggedIn: boolean; private notFoundPageComponent: Component; private currentKey = Date.now().toString(); @@ -89,7 +89,7 @@ export class Router extends EventEmitter<{ super(); this.routes = routes; - this.currentPath = currentPath; + //this.currentPath = currentPath; this.isLoggedIn = isLoggedIn; this.notFoundPageComponent = notFoundPageComponent; this.navigate(currentPath, null, false); diff --git a/packages/frontend/src/router.ts b/packages/frontend/src/router.ts index b861afa9a..5c01a79a2 100644 --- a/packages/frontend/src/router.ts +++ b/packages/frontend/src/router.ts @@ -545,12 +545,49 @@ export const mainRouter = new Router(routes, location.pathname + location.search window.history.replaceState({ key: mainRouter.getCurrentKey() }, '', location.href); +const scrollPosStore = new Map(); +let restoring = false; + +window.setInterval(() => { + if (!restoring) { + console.log('#########', window.history.state); + scrollPosStore.set(window.history.state?.key, window.scrollY); + } +}, 1000); + mainRouter.addListener('push', ctx => { window.history.pushState({ key: ctx.key }, '', ctx.path); + + restoring = true; + const scrollPos = scrollPosStore.get(ctx.key) ?? 0; + window.scroll({ top: scrollPos, behavior: 'instant' }); + + if (scrollPos !== 0) { + window.setTimeout(() => { + // 遷移直後はタイミングによってはコンポーネントが復元し切ってない可能性も考えられるため少し時間を空けて再度スクロール + window.scroll({ top: scrollPos, behavior: 'instant' }); + }, 100); + restoring = false; + } else { + restoring = false; + } +}); + +mainRouter.addListener('same', () => { + window.scroll({ top: 0, behavior: 'smooth' }); }); window.addEventListener('popstate', (event) => { mainRouter.replace(location.pathname + location.search + location.hash, event.state?.key); + + restoring = true; + const scrollPos = scrollPosStore.get(event.state?.key) ?? 0; + window.scroll({ top: scrollPos, behavior: 'instant' }); + window.setTimeout(() => { + // 遷移直後はタイミングによってはコンポーネントが復元し切ってない可能性も考えられるため少し時間を空けて再度スクロール + window.scroll({ top: scrollPos, behavior: 'instant' }); + restoring = false; + }, 100); }); export function useRouter(): Router {