I have a div that I want to change color when it scrolls into the viewport, and I'm trying to achieve this with the new intersectionObserver
method. I've set my parameters in the config callback, but I can't seem to get the observer itself to add the class to change the background color?
Any help would be amazing.
codepen: https://codepen.io/emilychews/pen/mXVBVK
The function inside the IntersectionObserver
constructor is called whenever an intersection changes. You can’t put observer.observe(box);
inside it.
Also, item
isn’t a DOM element — it’s an IntersectionObserverEntry
, so you can’t use .classList
on it. You probably meant to address item.target
.
Even if the above is corrected, your CSS won’t change, because you’ve used the #box
selector to set the background
to blue
, which has a higher specificity than .active
. An easy fix is to change #box
to .box
and as HTML use <div id="box" class="box"></div>
instead.
The corrected code would then look like this:
const config = {
root: null, // Sets the framing element to the viewport
rootMargin: "0px",
threshold: 0.5
},
box = document.getElementById("box"),
observer = new IntersectionObserver((entries) => entries
.forEach(({target: {classList}}) => classList.add("active")), config);
observer.observe(box);
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 300vh;
}
.box {
width: 100px;
height: 100px;
background: blue;
}
.active {
background: red;
}
<div id="box" class="box"></div>
Now you need some logic inside the callback:
entries.forEach(({target: {classList}, intersectionRatio}) => {
if(intersectionRatio > 0.5){
classList.add("active");
}
else{
classList.remove("active");
}
});
This will make the <div>
red when more than 50 % of it are visible.
const config = {
root: null, // Sets the framing element to the viewport
rootMargin: "0px",
threshold: 0.5
},
box = document.getElementById("box"),
observer = new IntersectionObserver((entries) => entries
.forEach(({target: {classList}, intersectionRatio}) => {
if(intersectionRatio > 0.5){
classList.add("active");
}
else{
classList.remove("active");
}
}), config);
observer.observe(box);
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 300vh;
}
.box {
width: 100px;
height: 100px;
background: blue;
}
.active {
background: red;
}
<div id="box" class="box"></div>