mirror of
https://github.com/ArthurDanjou/website.git
synced 2026-01-14 12:14:42 +01:00
50 lines
1.2 KiB
TypeScript
50 lines
1.2 KiB
TypeScript
import type {RouterConfig} from '@nuxt/schema'
|
|
|
|
function findHashPosition(hash: string): { el: string, behavior: ScrollBehavior, top: number } | undefined {
|
|
const el = document.querySelector(hash)
|
|
// vue-router does not incorporate scroll-margin-top on its own.
|
|
if (el) {
|
|
const top = Number.parseFloat(getComputedStyle(el).scrollMarginTop)
|
|
|
|
return {
|
|
el: hash,
|
|
behavior: 'smooth',
|
|
top,
|
|
}
|
|
}
|
|
}
|
|
|
|
// https://router.vuejs.org/api/#routeroptions
|
|
export default <RouterConfig>{
|
|
scrollBehavior(to, from, savedPosition) {
|
|
const nuxtApp = useNuxtApp()
|
|
|
|
// If history back
|
|
if (savedPosition) {
|
|
// Handle Suspense resolution
|
|
return new Promise((resolve) => {
|
|
nuxtApp.hooks.hookOnce('page:finish', () => {
|
|
setTimeout(() => resolve(savedPosition), 50)
|
|
})
|
|
})
|
|
}
|
|
|
|
// Scroll to heading on click
|
|
if (to.hash) {
|
|
return new Promise((resolve) => {
|
|
if (to.path === from.path) {
|
|
setTimeout(() => resolve(findHashPosition(to.hash)), 50)
|
|
}
|
|
else {
|
|
nuxtApp.hooks.hookOnce('page:finish', () => {
|
|
setTimeout(() => resolve(findHashPosition(to.hash)), 50)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// Scroll to top of window
|
|
return { top: 0 }
|
|
},
|
|
}
|