I have a website using vertical scroll snap. The website is divided into full width and height sections and I would like to style the navigation and other elements depending on which of these sections in in the viewport.
I have tried a lot of answers I have found online without success. The closest I can get it to work is this:
var targets = document.querySelectorAll('section')
var obsOptions = {
root: null, // measure against the viewport
threshold: .5 // how much of the element should be visible before handler is triggered
}
let handler = (entries, opts) => {
entries.forEach(entry => {
if (entry.intersectionRatio > opts.thresholds[0]) {
document.body.classList.remove(...document.body.classList);
document.body.classList.add(entry.target.id '-active');
}
})
}
targets.forEach(el => {
var observer = new IntersectionObserver(handler, obsOptions);
observer.observe(el);
})
This works well except it removes all the classes off the body and the WordPress theme adds its own which are necessary for it to function so I can't have that
If I remove the line about removing the classes - ALL the section ID's show as classes at the same time.
I thought the best way would be to not apply it to the body, but to a container that had no other classes - so I have wrapped everything in a container div with a class of
.full-page-container
I tried editing the code to this
var targets = document.querySelectorAll('section')
var obsOptions = {
root: null, // measure against the viewport
threshold: .5 // how much of the element should be visible before handler is triggered
}
let handler = (entries, opts) => {
entries.forEach(entry => {
if (entry.intersectionRatio > opts.thresholds[0]) {
document.full-page-container.classList.remove(...document.ful-page-container.classList);
document.full-page-container.classList.add(entry.target.id '-active');
}
})
}
targets.forEach(el => {
var observer = new IntersectionObserver(handler, obsOptions);
observer.observe(el);
})
but it doesn't work.
How does one apply this same effect to a div rather than the body
Any help would be much appreciated
Here is a codepen I have put together
https://codepen.io/shereewalker/pen/bGaqqmy
CodePudding user response:
In the remove you are spending the content of classList and I think therefore are removing all the classes.
I would suggest filtering the classList for classes that contain -active
(The class you add) and then removing those.
var targets = document.querySelectorAll('section')
var obsOptions = {
root: null, // measure against the viewport
threshold: .5 // how much of the element should be visible before handler is triggered
}
let handler = (entries, opts) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > opts.thresholds[0]) {
const classesToRemove = findClassesWithActive(document.body.classList);
if (classesToRemove.length > 0) {
document.body.classList.remove(classesToRemove);
}
document.body.classList.add(entry.target.id "-active");
}
});
};
targets.forEach(el => {
var observer = new IntersectionObserver(handler, obsOptions);
observer.observe(el);
})
function findClassesWithActive(classList) {
return classList.filter(c => c.includes('-active')
}