I have a strange issue with the VueJS Router and its built-in scrollBehaviour-feature.
I want to achieve that on back-navigation, the browser would scroll down to the original position where the user previously clicked for navigation into a child page.
I am using the built-in ScrollBehaviour Feature: https://router.vuejs.org/guide/advanced/scroll-behavior
My implementation is this:
const router = createRouter({
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Saved Position:', savedPosition)
resolve({ left: 0, top: savedPosition.top, y: savedPosition.top, behavior: 'smooth' });
}, 800)
})
} else {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ top: 0, behavior: 'smooth' });
}, 800)
})
}
},
So far, it doesn't work well. It most of the cases, the savedPosition
is just top: 0
.
Google Chrome Desktop: works mostly always, sometimes not
Google Chrome on iOS: don't work at all
Safari Desktop Mac: don't work at all. savedPosition is always `top: 0`
Safari iOS: don't work at all. savedPosition is always `top: 0`
Apparently I have to save the scroll position by myself. How can I do this and where?
i think i had the same problem, and "scroll-behaviour" feature didnt work for me either. in one of my projects i did this:
in router i added meta: { saveScrollPosition: true },
to routes i wanted to have scroll positions saved
then just using beforeEach:
router.beforeEach((to, from, next) => {
setTimeout(() => {
if (from.meta.saveScrollPosition) {
saveScrollPosition(from.path, window.scrollY);
}
next();
}, 0);
});
scrollManager.js:
let scrollPositions = {};
export function saveScrollPosition(path, position) {
scrollPositions[path] = position;
}
export function getScrollPosition(path) {
return scrollPositions[path] || 0;
}
then in every page i wanted the scroll to be restored(this is homepage as an example):
onMounted(() => {
const scrollY = getScrollPosition("/home");
window.scroll(0, scrollY);
});
and dont forget imports import { getScrollPosition } from "@/scrollManager";
i feel like this is kind of barbaric, but it worked for me at that time.