Context
As I work on developing a blog website, I aim to integrate a sticky element that dynamically updates according to the current year and month as users scroll through the content. This would provide a visual indication of the timeline for the listed blog articles.
When it comes to coding, my approach involves experimenting with HTML first, followed by CSS if necessary, and then JS as a last resort. I find this method efficient as it leverages existing features and minimizes the utilization of computing resources. However, I'm open to other perspectives on this practice.
Problem
The challenge lies in altering the style of elements when they become 'stuck'. In attempting this, I reviewed David Walsh's solution which utilizes IntersectionObserver
, but encountered glitches when applying it to multiple elements simultaneously.
The primary issue I am facing is that when dealing with multiple entries, the script erroneously identifies an element as 'pinned' when it reaches the bottom border of the window.
Code
Below is a snippet of the code, along with a corresponding jsfiddle demo.
//Implementing David Walsh's code using a loop
document.querySelectorAll(".myElement").forEach((i) => {
const observer = new IntersectionObserver(([i]) => i.target.classList.toggle("is-pinned", i.intersectionRatio < 1),
{threshold: [1]});
observer.observe(i);
})
#parent {
height: 2000px;
}
.myElement {
position: sticky;
top: -1px;
}
/* styles applied when the header is in sticky mode. The transition times contribute to an undesired effect */
.myElement.is-pinned {
color: red;
transition: color 0.3s, background-color 0.3s;
background-color: orange;
}
<div id="parent">
<!-- Including more than one 'hello' element. Adding br tags to introduce vertical space exceeding viewport height -->
<br><br><br><br>
<div class="myElement">Hello!</div>
<br><br><br><br>
<div class="myElement">Hello 2!</div>
<br><br><br><br>
<div class="myElement">Hello 3!</div>
<br><br><br><br>
<div class="myElement">Hello 4!</div>
<br><br><br><br>
<div class="myElement">Hello 5!</div>
<br><br><br><br>
<div class="myElement">Hello 6!</div>
<br><br><br><br>
<div class="myElement">Hello 7!</div>
<br><br><br><br>
<div class="myElement">Hello 8!</div>
</div>