Intersection Observer
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.
Vue Example
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.replace({ name: this.$route.name, hash: `#${sectionId}` })
}
}
}
}
Variable threshold
function doTheThing (el) {
el.classList.add('in-view');
}
const threshold = 0.5;
document.querySelectorAll('section').forEach(el => {
const elHeight = el.getBoundingClientRect().height;
var th = threshold;
// The element is too tall to ever hit the threshold - change threshold
if (elHeight > (window.innerHeight * threshold)) {
th = ((window.innerHeight * threshold) / elHeight) * threshold;
}
new IntersectionObserver(iEls => iEls.forEach(iEl => doTheThing(iEl)), {threshold: th}).observe(el);
});