nuxt
Version:
46 lines (45 loc) • 1.83 kB
JavaScript
import { useNuxtApp } from "#app/nuxt";
import { isChangingPage } from "#app/components/utils";
import { useRouter } from "#app/composables/router";
import { appPageTransition as defaultPageTransition } from "#build/nuxt.config.mjs";
export default {
scrollBehavior(to, from, savedPosition) {
const nuxtApp = useNuxtApp();
const behavior = useRouter().options?.scrollBehaviorType ?? "auto";
let position = savedPosition || void 0;
const routeAllowsScrollToTop = typeof to.meta.scrollToTop === "function" ? to.meta.scrollToTop(to, from) : to.meta.scrollToTop;
if (!position && from && to && routeAllowsScrollToTop !== false && isChangingPage(to, from)) {
position = { left: 0, top: 0 };
}
if (to.path === from.path) {
if (from.hash && !to.hash) {
return { left: 0, top: 0 };
}
if (to.hash) {
return { el: to.hash, top: _getHashElementScrollMarginTop(to.hash), behavior };
}
return false;
}
const hasTransition = (route) => !!(route.meta.pageTransition ?? defaultPageTransition);
const hookToWait = hasTransition(from) && hasTransition(to) ? "page:transition:finish" : "page:finish";
return new Promise((resolve) => {
nuxtApp.hooks.hookOnce(hookToWait, async () => {
await new Promise((resolve2) => setTimeout(resolve2, 0));
if (to.hash) {
position = { el: to.hash, top: _getHashElementScrollMarginTop(to.hash), behavior };
}
resolve(position);
});
});
}
};
function _getHashElementScrollMarginTop(selector) {
try {
const elem = document.querySelector(selector);
if (elem) {
return Number.parseFloat(getComputedStyle(elem).scrollMarginTop) + Number.parseFloat(getComputedStyle(document.documentElement).scrollPaddingTop);
}
} catch {
}
return 0;
}