Restore scroll position on navigation

This commit is contained in:
Volpeon 2024-01-03 16:23:02 +01:00
parent 96df8c25de
commit 8e9bf67d9a
No known key found for this signature in database
2 changed files with 39 additions and 2 deletions

View file

@ -78,7 +78,7 @@ export class Router extends EventEmitter<{
public current: Resolved; public current: Resolved;
public currentRef: ShallowRef<Resolved> = shallowRef(); public currentRef: ShallowRef<Resolved> = shallowRef();
public currentRoute: ShallowRef<RouteDef> = shallowRef(); public currentRoute: ShallowRef<RouteDef> = shallowRef();
private currentPath: string; private currentPath = '';
private isLoggedIn: boolean; private isLoggedIn: boolean;
private notFoundPageComponent: Component; private notFoundPageComponent: Component;
private currentKey = Date.now().toString(); private currentKey = Date.now().toString();
@ -89,7 +89,7 @@ export class Router extends EventEmitter<{
super(); super();
this.routes = routes; this.routes = routes;
this.currentPath = currentPath; //this.currentPath = currentPath;
this.isLoggedIn = isLoggedIn; this.isLoggedIn = isLoggedIn;
this.notFoundPageComponent = notFoundPageComponent; this.notFoundPageComponent = notFoundPageComponent;
this.navigate(currentPath, null, false); this.navigate(currentPath, null, false);

View file

@ -545,12 +545,49 @@ export const mainRouter = new Router(routes, location.pathname + location.search
window.history.replaceState({ key: mainRouter.getCurrentKey() }, '', location.href); window.history.replaceState({ key: mainRouter.getCurrentKey() }, '', location.href);
const scrollPosStore = new Map<string, number>();
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 => { mainRouter.addListener('push', ctx => {
window.history.pushState({ key: ctx.key }, '', ctx.path); 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) => { window.addEventListener('popstate', (event) => {
mainRouter.replace(location.pathname + location.search + location.hash, event.state?.key); 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 { export function useRouter(): Router {