MWCodebymw.de ↗
JavaScript

Elemente beim Scrollen einblenden mit IntersectionObserver

Bilder erst laden, wenn sie sichtbar werden, oder Abschnitte sanft einblenden – ganz ohne Scroll-Event-Gehacke. Der IntersectionObserver macht das effizient und in wenigen Zeilen.

„Blende die Abschnitte ein, sobald man hinscrollt" – so ein Effekt sieht auf einer Website edel aus. Früher hätte man dafür bei jedem scroll-Event Positionen ausgerechnet – das ruckelt und kostet Leistung. Heute nehme ich den IntersectionObserver: Der Browser sagt mir selbst Bescheid, wenn ein Element in den sichtbaren Bereich kommt.

Einblenden beim Scrollen

Erst das CSS für den sanften Übergang:

.reveal { opacity: 0; transform: translateY(24px); transition: opacity .6s, transform .6s; }
.reveal.is-visible { opacity: 1; transform: none; }

Dann der Observer – er beobachtet alle .reveal-Elemente und schaltet die Klasse um, sobald sie auftauchen:

const io = new IntersectionObserver((entries, obs) => {
  for (const entry of entries) {
    if (!entry.isIntersecting) continue;
    entry.target.classList.add('is-visible');
    obs.unobserve(entry.target);   // einmal reicht – spart Arbeit
  }
}, {
  threshold: 0.1,                  // ab 10 % Sichtbarkeit auslösen
  rootMargin: '0px 0px -10% 0px',  // etwas früher, bevor es ganz unten ist
});

document.querySelectorAll('.reveal').forEach(el => io.observe(el));

Bilder erst laden, wenn sie gebraucht werden

Dasselbe Prinzip spart Ladezeit: Das echte Bild steckt in data-src und wird erst gesetzt, wenn das Bild fast im Blick ist.

<img data-src="/gross/foto.webp" alt="" class="lazy">
const imgObserver = new IntersectionObserver((entries, obs) => {
  for (const entry of entries) {
    if (!entry.isIntersecting) continue;
    const img = entry.target;
    img.src = img.dataset.src;
    obs.unobserve(img);
  }
}, { rootMargin: '200px' });  // 200 px vorher laden, damit nichts „poppt"

document.querySelectorAll('img.lazy').forEach(img => imgObserver.observe(img));

Der Trick mit unobserve() ist wichtig: Sobald ein Element erledigt ist, hört der Observer auf, es zu beobachten – so bleibt die Seite auch bei hundert Elementen flüssig. Und loading="lazy" am <img> gibt es zwar nativ, aber der Observer gibt dir die volle Kontrolle über den Zeitpunkt und den Effekt.

So einen dezenten Scroll-Effekt baue ich auch in Kundenseiten ein. Wenn du eine schnelle, moderne Website brauchst, meld dich über bymw.de.

Quellen

#IntersectionObserver#Performance#Scroll#Lazy Loading#Vanilla JS

Du brauchst mehr als ein Snippet?

Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.

Projekt anfragen →