I made a simple on scroll animation in React however only the first section (excluding home component all other sections have section) gets the class applied on time. As for the rest of the sections, they get the class applied to them later when I have scrolled halfway past them.
import './App.css';
import Home from './components/Sections/Home';
import Clients from './components/Sections/Clients';
import AboutUs from './components/Sections/AboutUs';
import Career from './components/Sections/Career';
import Discover from './components/Sections/Discover';
import OurWork from './components/Sections/OurWork';
import Testimonial from './components/Sections/Testimonial';
import Plan from './components/Sections/Plan';
import Footer from './components/Sections/Footer';
import { useEffect } from 'react';
function App() {
useEffect(() => {
const triggerPoint = window.innerHeight / 5 * 4;
document.querySelector(".trigger").style.top = triggerPoint + "px";
const handleScroll = () => checkSections(triggerPoint)
window.addEventListener("scroll", handleScroll);
checkSections(triggerPoint);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
function checkSections(triggerPoint){
const sections = document.querySelectorAll("section");
console.log("window.innerheight",window.innerHeight);
console.log("triggerpoint",triggerPoint);
sections.forEach(section => {
const sectionTop = section.getBoundingClientRect().top;
console.log("sectiontop",sectionTop);
if(sectionTop < triggerPoint){
section.classList.add("on-scroll");
}else{
section.classList.remove("on-scroll")
}
})
}
return (
<div id="App" style={{position: "relative"}}>
<div className='trigger' style={{position: "fixed", left: "100px", background: "white", zIndex: "99", width: "50px", height: "50px"}}></div>
<Home />
<Clients />
<AboutUs />
<Career />
<Discover />
<OurWork />
<Testimonial />
<Plan />
<Footer />
</div>
);
}
export default App;
I tried to understand the problem myself by visualizing the triggerPoint
on the screen but due to inexperience I couldn’t understand what the problem was.
5
After using Intersection Observer as suggested by @Asplund I included Intersection Observer into the code and it works perfectly how I want.
The final code is:
useEffect(() => {
const discovers = document.querySelectorAll(".discover");
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
entry.target.classList.toggle("on-scroll", entry.isIntersecting);
if (entry.isIntersecting) {
observer.unobserve(entry.target);
}
});
},
{
threshold: 0.5,
},
);
discovers.forEach((discover) => {
observer.observe(discover);
});
return () => {
discovers.forEach((discover) => {
observer.unobserve(discover);
});
};
}, []);
It will work in React, if you are using vanilla js copy the code from within the useEffect
.