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
Debounce in Vanilla JavaScript – ohne Bibliothek
Eine Suche, die bei jedem Tastendruck feuert, überlastet den Server. Mit einer kleinen debounce-Funktion wartest du, bis der Nutzer kurz Pause macht – in wenigen Zeilen, ganz ohne Framework.
Verlässliches JSON aus einem LLM – mit Structured Outputs statt Hoffnung
Antworte nur mit JSON" reicht nicht – irgendwann kommt doch ein "Klar, hier ist dein JSON:" davor und dein JSON.parse() stürzt ab. Mit einem JSON-Schema erzwingst du garantiert gültige Struktur.
ChatGPT-Antworten live streamen im Browser (OpenAI, fetch + SSE)
Statt auf die komplette KI-Antwort zu warten, lässt du sie Wort für Wort erscheinen – wie im echten ChatGPT. So liest du den Server-Sent-Events-Stream der OpenAI-API mit reinem fetch, ohne Bibliothek.