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
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 →Verwandte Snippets
Web Worker – rechnen, ohne die Oberfläche einzufrieren
JavaScript hat im Browser genau einen Faden für alles: Klicks, Animationen, Layout – und deine Rechenschleife. Dauert die zwei Sekunden, ist die Seite zwei Sekunden lang tot. Ein Worker nimmt die Arbeit auf einen eigenen Faden.
Formulare ohne Neuladen abschicken – FormData und fetch
Ein Formular per JavaScript abzuschicken heißt nicht, jedes Feld einzeln auszulesen. FormData nimmt das ganze Formular, fetch schickt es weg – inklusive Dateien, und mit einer Fehlermeldung, die der Besucher versteht.
CustomEvent – Bausteine, die sich gegenseitig Bescheid sagen, ohne sich zu kennen
Sobald zwei Teile einer Seite aufeinander reagieren sollen, landet man schnell bei globalen Variablen oder Funktionsaufrufen quer durchs Projekt. Eigene Events entkoppeln das – mit denselben Mitteln, die der Browser selbst benutzt.