I want css keyframe animations to run 1 time when the bridge element is in the viewport. Intersect observer does this well, but the issue is the animations fire randomly when clicking on other parts of the element that have onClicks to show new text paragraphs.
The point was to call attention to the user that hey! you can click on these parts of the bridge element by showing a delayed box shadow when main element is in view. Maybe there is a better way to show users that an area is clickable, maybe there is a JS rule I am overlooking? Any suggestions appreciated – Thank you!
Example:
https://codepen.io/robyngraha/pen/LYaZMVg
HTML
<div class="scroll-container">
<!-- For Spacing -->
<h1>Scroll down....<br />Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus architecto voluptatem numquam, nihil ullam suscipit, odit placeat labore natus maxime laborum aliquam voluptates animi, dicta facere debitis earum beatae nemo. Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem totam aut fugiat nostrum animi, sed illum ad minima sint sequi nemo, labore, suscipit et reiciendis fuga corrupti! Provident, tempore ab. Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis enim ad quos incidunt culpa necessitatibus eveniet aut earum quia, est iste debitis eos quidem facilis facere? Velit temporibus esse adipisci?</h1>
<div class="bridge-container bridge">
<div id="first-brother" class="bridge-green" onclick="firstBro()" ></div>
<div id="second-brother" onclick="secondBro()"></div>
<div id="third-brother" onclick="thirdBro()"></div>
<div id="rmg">HELLO</div>
</div>
<div id="first-bro-text">
<p style="color:#225BBE;font-weight:900;">First Brother</p>
<p>So, the oldest brother, who was a combative man, asked for a wand more powerful than any in existence.
A wand that must always win battles for its owner. A wand worthy of a wizard who had conquered Death.
So, Death had crossed to an Elder Tree on the banks of the river, fashioned a wand from a branch that had hung there, and gave it to the oldest brother</p>
</div>
<div id="second-bro-text">
<p style="color:#225BBE;font-weight:900;">Second Brother</p>
<p>Then the second brother, who was an arrogant man, decided that he wanted to humiliate Death still further, and asked for the power to recall others from Death. So, Death picked up a stone from the riverbank and gave it to the second brother, and told him that the stone would have the power to bring back the dead.</p>
</div>
<div id="third-bro-text">
<p style="color:#225BBE;font-weight:900;">Third Brother</p>
<p>Finally, Death turned to the third brother. A humble man, he asked for something that would enable him to go forth from that place without being followed by Death. And so it was that Death reluctantly handed over his own Cloak of Invisibility. </p>
</div>
<div id="click-me">Click Me</div>
<!-- For Spacing -->
<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus architecto voluptatem numquam, nihil ullam suscipit, odit placeat labore natus maxime laborum aliquam voluptates animi, dicta facere debitis earum beatae nemo. Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem totam aut fugiat nostrum animi, sed illum ad minima sint sequi nemo, labore, suscipit et reiciendis fuga corrupti! Provident, tempore ab. Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis enim ad quos incidunt culpa necessitatibus eveniet aut earum quia, est iste debitis eos quidem facilis facere? Velit temporibus esse adipisci?</h1>
</div>
CSS
.scroll-container {
max-width: 480px;
}
/* Bridge CSS */
.bridge-container {
height:65px;
color:white;
border-radius: 8px;
display: flex;
gap: 2px;
justify-content: space-between;
font-size: 1.3rem;
background: black;
cursor: pointer;
background: linear-gradient(180deg, #28411F 20.31%, #000 100%);
}
/* center div */
#second-brother {
font-size: 1.8rem;
width: 80%;
margin: 0 auto;
position: relative;
display: flex;
align-items: center;
justify-content: center;
border-left: black solid 2px;
border-right: black solid 2px;
}
.animation {
animation-name: highlight;
animation-duration: 1s;
animation-iteration-count: 1;
}
@keyframes highlight {
0% {box-shadow: none;}
50% { box-shadow: 0 0px 10px 10px orange;}
100% {box-shadow: none;}
}
/* center changing text */
#second-brother::after {
content: "2nd";
position: relative;
}
/* outer left div */
#first-brother {
border-radius: 8px 0px 0px 8px;
width: 20%;
height: 65px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
line-height: 20px;
font-size: 1.5rem;
}
/* outer left div text */
#first-brother::after {
content: "1st";
position: relative;
}
/* outer right div */
#third-brother {
border-radius: 0px 8px 8px 0px;
width: 20%;
height: 65px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
line-height: 20px;
font-size: 1.5rem;
}
.animation2 {
animation-name: highlight2;
animation-delay: .5s;
animation-duration: 1s;
animation-iteration-count: 1;
}
@keyframes highlight2 {
0% {box-shadow: none;}
50% { box-shadow: 0 0px 10px 10px orange;}
100% {box-shadow: none;}
}
/* outer right div text */
#third-brother::after {
content: "3rd";
position: relative;
}
@media (max-width: 625px) {
#first-brother-left::after {
margin-left: 12px;
}
}
@media (max-width: 480px) {
#countdown-right, #countdown-left, #center-battery {
font-size: 1rem;
}
}
/* Brothers text */
@keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
#first-bro-text {
display: block;
animation: fadeIn .5s;
}
#second-bro-text {
display: none;
animation: fadeIn .5s;
}
#third-bro-text {
display: none;
animation: fadeIn .5s;
}
.bridge-green {
background: linear-gradient(180deg, #4A7938 20.31%, #000 100%);
animation: fadeIn 1s;
}
#click-me {
box-shadow: red;
}
JS
function firstBro() {
document.getElementById("first-bro-text").style.display = "block";
document.getElementById("second-bro-text").style.display="none";
document.getElementById("third-bro-text").style.display = "none";
document.getElementById("first-brother").classList.add("bridge-green");
document.getElementById("second-brother").classList.remove("bridge-green");
document.getElementById("third-brother").classList.remove("bridge-green");
}
function secondBro() {
document.getElementById("first-bro-text").style.display = "none";
document.getElementById("second-bro-text").style.display="block";
document.getElementById("third-bro-text").style.display = "none";
document.getElementById("first-brother").classList.remove("bridge-green");
document.getElementById("second-brother").classList.add("bridge-green");
document.getElementById("third-brother").classList.remove("bridge-green");
}
function thirdBro() {
document.getElementById("first-bro-text").style.display = "none";
document.getElementById("second-bro-text").style.display="none";
document.getElementById("third-bro-text").style.display = "block";
document.getElementById("first-brother").classList.remove("bridge-green");
document.getElementById("second-brother").classList.remove("bridge-green");
document.getElementById("third-brother").classList.add("bridge-green");
}
//battery animatiom
const bridge = document.querySelector('.bridge');
const secondBroEl = document.querySelector('#second-brother');
const thirdBroEl = document.querySelector('#third-brother');
const observer = new IntersectionObserver(entries => {
secondBroEl.classList.toggle('animation', entries[0].isIntersecting);
thirdBroEl.classList.toggle('animation2', entries[0].isIntersecting);
console.log(entries)
});
observer.observe(bridge);
I tried setting the animation-iteration-count to 1 in CSS but the animation starts over whenever clicking on 1st, 2nd or 3rd elements that have onClick functions.
I added an onClick function outside of the intersect observation element and the animations do not run, so it must be related to the element with the intersection observer.
I added an element with in the intersection observer without an onclick (Hello text) and the animations do not fire so the issue must be related to elements with an onclick.