I have a div with two spans inside it. The position of spans is that span1 uses a sticky position from the center of the div while span2 is at the bottom of the div. The idea is that, as the user scrolls, span1, which is initially at opacity 0 becomes visible and after further scrolling, span2 becomes visible. I tried achieving this by manually tweaking the points they become visible. Is there an optimal way to achieve this? I am attaching my code as reference
window.addEventListener('scroll', function() {
const message = document.querySelector('.message');
const deathSpan = document.querySelector('.message > span');
const vhDiv = document.querySelector('.vh');
const rect = message.getBoundingClientRect();
const windowHeight = window.innerHeight;
const fadeStart1 = windowHeight * 0.3;
const fadeEnd1 = windowHeight * 0.6;
const fadeStart2 = windowHeight * 0.5;
const fadeEnd2 = windowHeight * 0.9;
if (rect.top <= fadeEnd1 && rect.bottom >= fadeStart1) {
let opacity1 = (fadeEnd1 - rect.top) / (fadeEnd1 - fadeStart1);
opacity1 = Math.min(Math.max(opacity1, 0), 1);
deathSpan.style.opacity = opacity1;
} else {
deathSpan.style.opacity = 0;
}
if (rect.top <= fadeEnd2 && rect.bottom >= fadeStart2) {
let opacity2 = (fadeEnd2 - rect.top) / (fadeEnd2 - fadeStart2);
opacity2 = Math.min(Math.max(opacity2, 0), 1);
vhDiv.style.opacity = opacity2;
} else {
vhDiv.style.opacity = 0;
}
});
.above-divs a{
font-size:10rem;
background-color: black;
color: white;
}
.message {
width: 100%;
height: 150vh;
display: flex;
position: relative;
background-color: rgb(0, 0, 0);
align-items: center;
}
.message span {
font-size: 10vw;
color: rgb(255, 255, 255);
}
.message>span {
position: sticky;
top: 50%;
opacity: 0;
transition: opacity 0.5s ease;
}
.vh {
position: absolute;
bottom: 0;
right: 10%;
opacity: 0;
transition: opacity 0.5s ease;
}
<div class="above-divs">
<a href="">hello</a>
</div>
<div class="message">
<span>Text1 (span1)</span>
<div class="vh">
<span>Text2 (span2)</span>
</div>
</div>
2
Answers
This might be useful: Intersection Observer API MDN
This API provides an efficient way to track visibility changes of elements relative to the viewport.
You can try doing something like:
Indeed IntersectionObserver is the way, but you don’t need to specify one for each element
Your HTML/CSS structure is a bit weird but I more or less followed it for a working example