I am basically trying to have the exact same routing behaviour on my site as here: https://router.vuejs.org/guide/#html. Notice when you scroll down the link changes to https://router.vuejs.org/guide/#javascript. Scroll back up and it is vice versa. When reloading the page your position gets saved.
I added the following scroll behavior to my router:
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return { selector: to.hash }
} else if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 }
}
Now I can jump to an anchor with a link and the route changes. That's about as far as I get. Kind of ironic to pick the Vue Router website as an example, but anyway - how can I replicate its behaviour?
You could set up an IntersectionObserver
and observe all sections on the page. When a section enters the view, take the section's id and update the route:
<div class="section" id="html">
...
</div>
<div class="section" id="javascript">
...
</div>
data () {
return {
sectionObserver: null
}
},
mounted () {
this.observeSections()
},
methods: {
observeSections() {
try {
this.sectionObserver.disconnect()
} catch (error) {}
const options = {
rootMargin: '0px 0px',
threshold: 0
}
this.sectionObserver = new IntersectionObserver(this.sectionObserverHandler, options)
// Observe each section
const sections = document.querySelectorAll('.section')
sections.forEach(section => {
this.sectionObserver.observe(section)
})
},
sectionObserverHandler (entries) {
for (const entry of entries) {
if (entry.isIntersecting) {
const sectionId = entry.target.id
// Push sectionId to router here
this.$router.push({ name: this.$route.name, hash: `#${sectionId}` })
}
}
}
}
As @Sigi mentioned in the comment, you can use this.$router.replace()
instead of this.$router.push()
in the sectionObserverHandler
, to avoid cluttering the history.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With