Ein wenig Animation auf einer Website kann für etwas Flair sorgen, Benutzer beeindrucken und ihre Aufmerksamkeit erregen. Man könnte sie sofort beim Laden der Seite ausführen, egal wo sie sich auf der Seite befinden. Aber was ist, wenn Ihre Website ziemlich lang ist, sodass der Benutzer einige Zeit braucht, um zu diesem Element zu scrollen? Sie könnten es verpassen.
Man könnte sie die ganze Zeit laufen lassen, aber vielleicht ist die Animation am besten so gestaltet, dass man den Anfang davon sicher sieht. Der Trick ist, die Animation zu starten, wenn der Benutzer zu diesem Element herunterscrollt – eine scroll-ausgelöste Animation, wenn man so will.
Um dies anzugehen, verwenden wir Scroll-Trigger. Wenn der Benutzer zu einem bestimmten Element herunterscrollt, können wir dieses Ereignis nutzen, um etwas zu tun. Es könnte alles sein, sogar der Beginn einer Animation. Es könnte sogar scroll-ausgelöstes Lazy Loading für Bilder oder Lazy Loading eines ganzen Kommentarbereichs sein. Auf diese Weise zwingen wir Benutzer nicht, Elemente herunterzuladen, die beim anfänglichen Seitenaufruf nicht im Viewport sind. Viele Benutzer scrollen vielleicht gar nicht nach unten, sodass wir ihnen (und uns) Bandbreite und Ladezeit wirklich sparen.
Scroll-Trigger sind sehr nützlich. Es gibt viele Bibliotheken, die Sie zur Implementierung verwenden können, wie z. B. Greensocks beliebtes ScrollTrigger-Plugin. Aber Sie müssen keine Drittanbieter-Bibliothek verwenden, insbesondere nicht für ziemlich einfache Ideen. Tatsächlich können Sie es selbst mit nur einer Handvoll Vanilla JavaScript implementieren. Das werden wir in diesem Artikel tun.
So erstellen wir unser scroll-ausgelöstes Ereignis
- Erstellen Sie eine Funktion namens
scrollTrigger, die wir auf bestimmte Elemente anwenden können - Wenden Sie eine
.active-Klasse auf ein Element an, wenn es in den Viewport gelangt - Animieren Sie diese .
active-Klasse mit CSS
Es gibt Zeiten, in denen das Hinzufügen einer .active-Klasse nicht ausreicht. Zum Beispiel möchten wir vielleicht stattdessen eine benutzerdefinierte Funktion ausführen. Das bedeutet, wir sollten eine benutzerdefinierte Funktion übergeben können, die ausgeführt wird, wenn das Element sichtbar ist. So
scrollTrigger('.loader', {
cb: function(el) {
el.innerText = 'Loading ...'
loadContent()
}
})
Wir werden auch versuchen, Scroll-Trigger für ältere Browser zu unterstützen, die sie nicht unterstützen.
Aber zuerst die IntersectionObserver API
Das wichtigste JavaScript-Feature, das wir verwenden werden, ist der Intersection Observer. Diese API bietet eine Möglichkeit, asynchron Änderungen an der Schnittmenge eines Zielelements zu beobachten – und das auf eine performantere Weise als das Beobachten von scroll-Ereignissen. Wir werden IntersectionObserver verwenden, um zu überwachen, wann das Scrollen den Punkt erreicht, an dem bestimmte Elemente auf der Seite sichtbar sind.
Lasst uns mit dem Erstellen des Scroll-Triggers beginnen
Wir möchten eine Funktion namens scrollTrigger erstellen, und diese Funktion sollte einen Selektor als Argument entgegennehmen.
function scrollTrigger(selector) {
// Multiple element can have same class/selector,
// so we are using querySelectorAll
let els = document.querySelectorAll(selector)
// The above `querySelectorAll` returns a nodeList,
// so we are converting it to an array
els = Array.from(els)
// Now we are iterating over the elements array
els.forEach(el => {
// `addObserver function` will attach the IntersectionObserver to the element
// We will create this function next
addObserver(el)
})
}
// Example usage
scrollTrigger('.scroll-reveal')
Erstellen wir nun die Funktion addObserver, die wir mit IntersectionObserver an das Element anhängen möchten
function scrollTrigger(selector){
let els = document.querySelectorAll(selector)
els = Array.from(els)
els.forEach(el => {
addObserver(el)
})
}
function addObserver(el){
// We are creating a new IntersectionObserver instance
let observer = new IntersectionObserver((entries, observer) => { // This takes a callback function that receives two arguments: the elements list and the observer instance.
entries.forEach(entry => {
// `entry.isIntersecting` will be true if the element is visible
if(entry.isIntersecting) {
entry.target.classList.add('active')
// We are removing the observer from the element after adding the active class
observer.unobserve(entry.target)
}
})
})
// Adding the observer to the element
observer.observe(el)
}
// Example usage
scrollTrigger('.scroll-reveal')
Wenn wir dies tun und zu einem Element mit der Klasse .scroll-reveal scrollen, wird eine .active-Klasse zu diesem Element hinzugefügt. Beachten Sie jedoch, dass die active-Klasse hinzugefügt wird, sobald ein kleiner Teil des Elements sichtbar ist.
Aber das könnte übertrieben sein. Stattdessen möchten wir vielleicht, dass die .active-Klasse hinzugefügt wird, sobald ein *größerer* Teil des Elements sichtbar ist. Glücklicherweise akzeptiert IntersectionObserver einige Optionen dafür als zweites Argument. Wenden wir diese auf unsere scrollTrigger-Funktion an
// Receiving options as an object
// If the user doesn't pass any options, the default will be `{}`
function scrollTrigger(selector, options = {}) {
let els = document.querySelectorAll(selector)
els = Array.from(els)
els.forEach(el => {
// Passing the options object to the addObserver function
addObserver(el, options)
})
}
// Receiving options passed from the scrollTrigger function
function addObserver(el, options) {
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
entry.target.classList.add('active')
observer.unobserve(entry.target)
}
})
}, options) // Passing the options object to the observer
observer.observe(el)
}
// Example usage 1:
// scrollTrigger('.scroll-reveal')
// Example usage 2:
scrollTrigger('.scroll-reveal', {
rootMargin: '-200px'
})

Und schon sind unsere ersten beiden Tagesordnungspunkte erfüllt!
Gehen wir zum dritten Punkt über – dem Hinzufügen der Möglichkeit, eine Callback-Funktion auszuführen, wenn wir zu einem Ziel-Element scrollen. Insbesondere übergeben wir die Callback-Funktion in unserem Options-Objekt als cb
function scrollTrigger(selector, options = {}) {
let els = document.querySelectorAll(selector)
els = Array.from(els)
els.forEach(el => {
addObserver(el, options)
})
}
function addObserver(el, options){
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting){
if(options.cb) {
// If we've passed a callback function, we'll call it
options.cb(el)
} else{
// If we haven't, we'll just add the active class
entry.target.classList.add('active')
}
observer.unobserve(entry.target)
}
})
}, options)
observer.observe(el)
}
// Example usage:
scrollTrigger('.loader', {
rootMargin: '-200px',
cb: function(el){
el.innerText = 'Loading...'
// Done loading
setTimeout(() => {
el.innerText = 'Task Complete!'
}, 1000)
}
})

Großartig! Es gibt noch eine letzte Sache, um die wir uns kümmern müssen: die Unterstützung älterer Browser. Bestimmte Browser unterstützen möglicherweise IntersectionObserver nicht. Lassen Sie uns diesen Fall also in unserer addObserver-Funktion behandeln
function scrollTrigger(selector, options = {}) {
let els = document.querySelectorAll(selector)
els = Array.from(els)
els.forEach(el => {
addObserver(el, options)
})
}
function addObserver(el, options) {
// Check if `IntersectionObserver` is supported
if(!('IntersectionObserver' in window)) {
// Simple fallback
// The animation/callback will be called immediately so
// the scroll animation doesn't happen on unsupported browsers
if(options.cb){
options.cb(el)
} else{
entry.target.classList.add('active')
}
// We don't need to execute the rest of the code
return
}
let observer = new IntersectionObserver((entries, observer) =>; {
entries.forEach(entry => {
if(entry.isIntersecting) {
if(options.cb) {
options.cb(el)
} else{
entry.target.classList.add('active')
}
observer.unobserve(entry.target)
}
})
}, options)
observer.observe(el)
}
// Example usages:
scrollTrigger('.intro-text')
scrollTrigger('.scroll-reveal', {
rootMargin: '-200px',
})
scrollTrigger('.loader', {
rootMargin: '-200px',
cb: function(el){
el.innerText = 'Loading...'
setTimeout(() => {
el.innerText = 'Task Complete!'
}, 1000)
}
})
Hier ist noch einmal die Live-Demo
Das war alles für diese kleine Reise! Ich hoffe, Sie haben sie genossen und dabei etwas Neues gelernt.
Mit diesem Tutorial sollte es einfach sein, skrollr nachzubauen, eines meiner Lieblings-Jquery-Plugins von früher.
Ich denke, das Aufrufen von observer.observe anstelle des Erstellens eines neuen Observers für jedes Element ist für den Browser leichter, wenn die Optionen und der Callback gleich sind.
Vielen Dank, dank Ihres Artikels kann ich meinen eigenen Scroll- und Reveal-Effekt für Landingpages erstellen.