I have a simple setup using intersectionObserver adding a class to an element when the element is intersecting.
Which works fine if only ONE element at a time scrolls into view.
let lazyLoadSvg = document.getElementsByClassName('geometry-animation')
console.log(lazyLoadSvg)
for(let i = 0; i < lazyLoadSvg.length; i++){
const observer2 = new IntersectionObserver(entries => {
// Loop over the entries
entries.forEach(entry => {
// If the element is visible
if (entry.isIntersecting) {
// Run the animation
targetGeometry = entry.target.children[0].children[0].getElementsByTagName('g');
setTimeout(function() {
for(let i = 0; i < targetGeometry.length; i++){
setTimeout(function() {
targetGeometry[i].classList.add('geometry-active');
}, 50 * i);
}
}, 1000)
}
});
});
// Tell the observer which elements to track
observer2.observe(lazyLoadSvg[i]);
}
But this doesn't work if there is more than one element intersecting at once... If there are multiple elements with the same Y position, only one of them will run the animation.
Any suggestions or ideas as to why this might be happening?
Here is the full code snippet :
let lazyLoadSvg = document.getElementsByClassName('geometry-animation')
console.log(lazyLoadSvg)
for(let i = 0; i < lazyLoadSvg.length; i++){
const observer2 = new IntersectionObserver(entries => {
// Loop over the entries
entries.forEach(entry => {
// If the element is visible
if (entry.isIntersecting) {
// Run the animation
targetGeometry = entry.target.children[0].children[0].getElementsByTagName('g');
setTimeout(function() {
for(let i = 0; i < targetGeometry.length; i++){
setTimeout(function() {
targetGeometry[i].classList.add('geometry-active');
}, 50 * i);
}
}, 1000)
}
});
});
// Tell the observer which elements to track
observer2.observe(lazyLoadSvg[i]);
}
.geometry-animation svg g g {
opacity: 0;
transition: all ease-in-out 400ms;
}
.geometry-animation svg g g.geometry-active {
opacity: 1;
}
/*
Everything below this is general page styling
*/
.main-grid {
display: grid;
grid-template-columns: 1fr 18fr 1fr;
}
.main-content {
grid-column: 2 / 3;
grid-row: 1 / 2;
overflow: hidden;
}
.main-copy {
margin: auto;
width: 78.1%;
transition: all ease-in-out 0.8s;
}
.grid-template {
display: grid;
height: 100%;
}
.gt-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.gt-item p.style-1 {
margin-top: 5%;
}
.gt-item p.style-2 {
font-size: 16px;
line-height: 24px;
padding-left: 28px;
padding-right: 20px;
padding-bottom: 20px;
}
.gt-item p.style-2.underline {
color: #f22450;
text-decoration: underline;
}
.gt-padding {
padding: 10%;
}
.gt-padding > * {
padding-bottom: 8%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="fill" style="height: 100vh;"></div>
<div class="main-grid">
<div class="main-content main-copy" style="overflow: visible;">
<div class="grid-template" style="grid-template-columns: repeat(3, 1fr); gap: 5vw; height: 750px; margin-top: 150px; margin-bottom: 150px; color: white;">
<!-- The div below is repeated three times -->
<div style="height: 100%;background-color: #15141b; justify-content: flex-start;" class="gt-item box-shadow">
<div class="gt-padding gt-item" style="justify-content: flex-start; width: 80%;">
<div class="geometry-animation" style="width: 75%;">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500" style="enable-background:new 0 0 500 500; fill:#E4E030;" xml:space="preserve">
<g>
<g class="svg-animated">
<linearGradient id="SVGID_83_" gradientUnits="userSpaceOnUse" x1="50.5953" y1="366.6901" x2="454.8215" y2="133.3099" gradientTransform="matrix(-4.163336e-17 0.2146 -0.2146 -4.163336e-17 208.488 214.677)">
<stop offset="0.1058" style="stop-color:#E4E030"/>
<stop offset="0.2778" style="stop-color:#E8E7E7"/>
<stop offset="0.5847" style="stop-color:#E8E7E7"/>
<stop offset="0.6434" style="stop-color:#E8E7E7;stop-opacity:0.8728"/>
<stop offset="1" style="stop-color:#E8E7E7;stop-opacity:0.5"/>
</linearGradient>
<polygon class="st82" points="204.8,282.3 204.8,255.5 191.4,232.3 168.2,218.9 141.4,218.9 118.2,232.3 104.8,255.5 104.8,282.3
118.2,305.5 141.4,318.9 168.2,318.9 191.4,305.5"/>
</g>
</g>
</svg>
</div>
<h1 style="width: 100%; font-size: 40px; font-weight: 800;">Yellow</h1>
<p style="border-top: solid 1px #333140; padding-top: 10%; color: grey;">A yellow circle should appear above this text when scrolled into view</p>
</div>
</div>
<!-- The div above is repeated three times -->
<div style="height: 100%;background-color: #15141b; justify-content: flex-start;" class="gt-item box-shadow">
<div class="gt-padding gt-item" style="justify-content: flex-start; width: 80%;">
<div class="geometry-animation" style="width: 75%;">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500" style="enable-background:new 0 0 500 500; fill:#E4E030;" xml:space="preserve">
<g>
<g class="svg-animated">
<linearGradient id="SVGID_83_" gradientUnits="userSpaceOnUse" x1="50.5953" y1="366.6901" x2="454.8215" y2="133.3099" gradientTransform="matrix(-4.163336e-17 0.2146 -0.2146 -4.163336e-17 208.488 214.677)">
<stop offset="0.1058" style="stop-color:#E4E030"/>
<stop offset="0.2778" style="stop-color:#E8E7E7"/>
<stop offset="0.5847" style="stop-color:#E8E7E7"/>
<stop offset="0.6434" style="stop-color:#E8E7E7;stop-opacity:0.8728"/>
<stop offset="1" style="stop-color:#E8E7E7;stop-opacity:0.5"/>
</linearGradient>
<polygon class="st82" points="204.8,282.3 204.8,255.5 191.4,232.3 168.2,218.9 141.4,218.9 118.2,232.3 104.8,255.5 104.8,282.3
118.2,305.5 141.4,318.9 168.2,318.9 191.4,305.5"/>
</g>
</g>
</svg>
</div>
<h1 style="width: 100%; font-size: 40px; font-weight: 800;">Yellow</h1>
<p style="border-top: solid 1px #333140; padding-top: 10%; color: grey;">A yellow circle should appear above this text when scrolled into view</p>
</div>
</div>
<div style="height: 100%;background-color: #15141b; justify-content: flex-start;" class="gt-item box-shadow">
<div class="gt-padding gt-item" style="justify-content: flex-start; width: 80%;">
<div class="geometry-animation" style="width: 75%;">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500" style="enable-background:new 0 0 500 500; fill:#E4E030;" xml:space="preserve">
<g>
<g class="svg-animated">
<linearGradient id="SVGID_83_" gradientUnits="userSpaceOnUse" x1="50.5953" y1="366.6901" x2="454.8215" y2="133.3099" gradientTransform="matrix(-4.163336e-17 0.2146 -0.2146 -4.163336e-17 208.488 214.677)">
<stop offset="0.1058" style="stop-color:#E4E030"/>
<stop offset="0.2778" style="stop-color:#E8E7E7"/>
<stop offset="0.5847" style="stop-color:#E8E7E7"/>
<stop offset="0.6434" style="stop-color:#E8E7E7;stop-opacity:0.8728"/>
<stop offset="1" style="stop-color:#E8E7E7;stop-opacity:0.5"/>
</linearGradient>
<polygon class="st82" points="204.8,282.3 204.8,255.5 191.4,232.3 168.2,218.9 141.4,218.9 118.2,232.3 104.8,255.5 104.8,282.3
118.2,305.5 141.4,318.9 168.2,318.9 191.4,305.5"/>
</g>
</g>
</svg>
</div>
<h1 style="width: 100%; font-size: 40px; font-weight: 800;">Yellow</h1>
<p style="border-top: solid 1px #333140; padding-top: 10%; color: grey;">A yellow circle should appear above this text when scrolled into view</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
try to change IntersectionObserver
threshold and set it to 0
.
Also you don't need to make IntersectionObserver
instance for every lazyLoadSvg
item; so move the IntersectionObserver
creation out of the loop.
I made this sandbox to mimic your case and it is working fine.
Hope this is useful for you.