After clicking a link on the app, I noticed that the Router does scroll to the correct hash location, but it always seems to be one element too high on the page. This issue occurs even though the scrolling functionality is working fine. For instance, if my page structure is as follows:
<template>
<div id="div1">Div1</div>
<div id="div2">Div2</div>
<div id="div3">Div3</div>
<div id="div4">Div4</div>
</template>
When I click a link that should go to hash "div3," it actually scrolls me to the top of div2 instead. Only a few elements are scrolled to correctly. Could this be due to some setting related to page margins?
Here's the snippet of code for the Router:
const router = new VueRouter({
routes,
mode: 'history',
base: "/",
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash,
behavior: 'smooth',
}
} else {
return { x: 0, y: 0 }
}
}
})
Below is an example of how the hash routing is called in the code:
if (item.title == "Mission") {
router.push({name: 'Explore', hash: '#mission-statement'});
} else if (item.title == "Our Story") {
router.push({name: 'Explore', hash: '#our-story-container'});
} else if (item.title == "Shared principles") {
router.push({name: 'Explore', hash: '#shared-principles-container'});
} else if (item.title == "Volunteer Opportunities") {
router.push({name: 'Explore', hash: '#volunteer-container'});
} else if (item.title == "Gallery") {
router.push({name: 'Explore', hash: '#galleries'});
} else if (item.title == "Living") {
router.push({name: 'Explore', hash: '#living-container'});
} else if (item.title == "Contact Us") {
router.push({name: 'Explore', hash: '#contact-us-container'});
} else {
router.push("/explore")
}
SOLUTION:
Thanks to IVO GELOV's answer, I was able to update the scroll behavior function with the following code, and now everything works as expected.
scrollBehavior (to, from, savedPosition) {
let position = {}
if (to.hash) {
position = {
selector: to.hash,
offset: { x: 0, y: 100 },
behavior: 'smooth',
}
} else {
position = { x: 0, y: 0 }
}
return new Promise((resolve) => {
setTimeout(() => {
resolve(position)
}, 100)
})
}