Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to detect when an element becomes visible

Short answer

IntersectionObserver calls a function when observed elements enter or leave the visible area:

<style>
  .box { height: 150px; margin: 400px 0; background: #ddd; transition: background 0.5s; }
  .box.visible { background: #4caf50; }
</style>
<div class="box"></div>
<div class="box"></div>
<script>
  const observer = new IntersectionObserver((entries) => {
    for (const entry of entries) {
      entry.target.classList.toggle('visible', entry.isIntersecting);
    }
  });
  document.querySelectorAll('.box').forEach((box) => observer.observe(box));
</script>

Only once

For lazy loading, stop observing the element after the first appearance:

const observer = new IntersectionObserver((entries) => {
  for (const entry of entries) {
    if (entry.isIntersecting) {
      entry.target.src = entry.target.dataset.src;
      observer.unobserve(entry.target);
    }
  }
}, { rootMargin: '200px' });
 
document.querySelectorAll('img[data-src]').forEach((img) => observer.observe(img));

Common mistake

For images there is a simpler way that needs no JavaScript at all: the attribute loading="lazy".

<img src="photo.jpg" loading="lazy" alt="Photo">

Thanks for reading!

Donate to the site — we work hard for you.