To create an intersection observer similar to the one shown in this example, you can utilize the code provided below:
<template>
<div>
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API">
Intersection observer example
</a>
<p
v-observe-visibility="{
callback: resetHashUrl,
intersection: {
threshold: 0.5,
},
}"
style="background-color: hsl(0, 0%, 80%); height: 100vh"
>
top block (triggered at 50% of the block)
</p>
<p
v-observe-visibility="{
callback: (isVisible, entry) => pushNewHash(isVisible, entry, 'center'),
intersection: {
threshold: 0.7,
},
}"
style="background-color: hsl(210, 17%, 40%); color: hsl(0, 0%, 100%); height: 100vh"
>
center block (triggered if at least 70% of the block visible aka threshold value)
</p>
<p
v-observe-visibility="{
callback: (isVisible, entry) => pushNewHash(isVisible, entry, 'end'),
intersection: {
threshold: 0.3,
},
}"
style="background-color: hsl(210, 50%, 13%); color: hsl(0, 0%, 100%); height: 100vh"
>
end block (triggered if at least 30% of the block visible aka threshold value)
</p>
</div>
</template>
<script>
import Vue from 'vue'
import { ObserveVisibility } from 'vue-observe-visibility'
Vue.directive('observe-visibility', ObserveVisibility)
export default {
methods: {
resetHashUrl(isVisible, _entry) {
if (isVisible) history?.replaceState(null, null, ' ')
},
pushNewHash(isVisible, _entry, newHash) {
if (isVisible) location.hash = newHash
},
},
}
</script>
This solution relies on vue-observe-visibility and requires minimal configuration.
If you're interested in a simpler scroll-spy functionality like the one demonstrated here, you can opt for the package provided at https://github.com/ibufu/vue2-scrollspy
For a more tailored example, consider the snippet of code below that applies classes based on the route or specific parameter:
<template>
<div>
<button :class="{ 'custom-class': isOnSpecificPath('/test') }">Click me</button>
<button :class="{ 'custom-class': isOnSpecificPath('/index') }">Click me</button>
</div>
</template>
<script>
export default {
methods: {
isOnSpecificPath(pathToTest) {
return this.$route.path === pathToTest
},
},
}
</script>
<style>
.custom-class {
color: hsl(39, 100%, 46%);
font-weight: 700;
}
</style>
https://i.sstatic.net/zXETJ.png