Guten Tag, Freunde!Überblick
Mit der Intersection Observer API (IOA) kann eine Anwendung den Schnittpunkt eines Elements (Ziels) mit seinem übergeordneten Element (Root) oder Ansichtsfenster (Ansichtsfenster) asynchron beobachten. Mit anderen Worten, diese API ruft jedes Mal eine bestimmte Funktion auf, wenn sich das Zielelement mit root oder viewport überschneidet.Anwendungsbeispiele:- Faules oder faules Laden von Bildern
- endloses Scrollen von Seiten
- Empfangen von Informationen über die Sichtbarkeit von Werbung zum Zwecke der Berechnung der Kosten für Impressionen
- Starten eines Prozesses oder einer Animation im Sichtfeld des Benutzers
Um mit IOA zu arbeiten, müssen Sie den Konstruktor verwenden, um ein Beobachterobjekt mit zwei Parametern zu erstellen - einer Rückruffunktion und Einstellungen:
let options = {
root: document.querySelector('.scroll-list'),
rootMargin: '5px',
threshold: 0.5
}
let callback = function(entries, observer){
...
}
let observer = new IntersectionObserver(callback, options)
Die Einstellungen:- root - ein Element, das als Ansichtsfenster für das Ziel fungiert (Vorfahr des Zielelements oder null für das Ansichtsfenster)
- rootMargin - Ränder um root (Rand in CSS, standardmäßig sind alle Ränder 0)
- Schwelle - eine Zahl oder ein Array von Zahlen, die den akzeptablen Prozentsatz der Schnittmenge von Ziel und Wurzel angeben
Als nächstes wird das Zielelement erstellt, das der Beobachter beobachtet:let target = document.querySelector('.list-item')
observer.observe(target)
Der Rückrufaufruf gibt ein Objekt zurück, das Datensätze von Änderungen enthält, die am Zielelement aufgetreten sind:let callback = (entries, observer) => {
entries.forEach(entry => {
})
}
Das Netzwerk ist voll von theoretischen Informationen, aber ziemlich viel Material über die Praxis der Verwendung von IOA. Ich beschloss, diese Lücke ein wenig zu füllen.Beispiele
Faules (verzögertes) Laden von Bildern
Aufgabe: Bilder hochladen (anzeigen), während der Benutzer die Seite scrollt.Der Code:
window.onload = () => {
const options = {
root: null,
rootMargin: '0px',
threshold: 0.5
}
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const lazyImg = entry.target
console.log(lazyImg)
lazyImg.style.background = 'deepskyblue'
observer.unobserve(lazyImg)
}
})
}, options)
const arr = document.querySelectorAll('img')
arr.forEach(i => {
observer.observe(i)
})
}
Ergebnis: Der
Hintergrund des Containers außerhalb des Ansichtsfensters ist weiß.
Wenn Sie den Betrachtungsbereich um die Hälfte überqueren, ändert sich der Hintergrund in Himmelblau.→ Codepen→ GithubBildersatz
Aufgabe: Ändern Sie das Platzhalterbild in das Original, wenn der Benutzer die Seite scrollt.Der Code:window.onload = () => {
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log(entry)
entry.target.src = entry.target.dataset.src
observer.unobserve(entry.target)
}
})
}, { threshold: 0.5 })
document.querySelectorAll('img').forEach(img => observer.observe(img))
}
Ergebnis:
Das erste Bild wird hochgeladen, da es sich im Anzeigebereich befindet. Der zweite ist Platzhalter.
Wenn Sie weiter scrollen, wird der Platzhalter durch das Originalbild ersetzt.→ Codepen→ GithubContainerhintergrund ändern
Aufgabe: Ändern des Hintergrunds des Containers, wenn der Benutzer die Seite hin und zurück scrollt.Der Code:window.addEventListener('load', event => {
let box = document.querySelector('div')
let prevRatio = 0.0
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
let curRatio = entry.intersectionRatio
curRatio > prevRatio ? entry.target.style.background = `rgba(40,40,190,${curRatio})` : entry.target.style.background = `rgba(190,40,40,${curRatio})`
prevRatio = curRatio
})
}, {
threshold: buildThresholdList()
})
observer.observe(box)
function buildThresholdList() {
let thresholds = []
let steps = 20
for (let i = 1.0; i <= steps; i++) {
let ratio = i / steps
thresholds.push(ratio)
}
return thresholds
}
})
Ergebnis: Der
Hintergrund des Containers wechselt von hellblau ...
über blau ...
zu hellrot.→ Codepen→ GithubArbeite mit Video
Aufgabe: Halten Sie das laufende Video an und starten Sie es erneut, je nachdem, welches Video in den Anzeigebereich fällt.Der Code:window.onload = () => {
let video = document.querySelector('video')
let observer = new IntersectionObserver(() => {
if (!video.paused) {
video.pause()
} else if(video.currentTime != 0) {
video.play()
}
}, { threshold: 0.4 })
observer.observe(video)
}
Ergebnis:
Während sich das Video im Anzeigebereich befindet, wird es abgespielt.
Sobald das Video den Anzeigebereich um mehr als 40% überschreitet, wird die Wiedergabe unterbrochen. Wenn Sie den Anzeigebereich> 40% des Videos erreichen, wird die Wiedergabe fortgesetzt.→ Codepen→ GithubFortschritt der Seitenansicht
Aufgabe: Zeigen Sie den Fortschritt des Anzeigens der Seite an, während der Benutzer die Seite scrollt.Der Code:
let p = document.querySelector('p')
let n = 0
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting){
p.textContent = `${n++} div viewed`
observer.unobserve(entry.target)
}
})
}, {threshold: 0.9})
document.querySelectorAll('div').forEach(div => observer.observe(div))
Ergebnis: Die
Seite wurde gerade geladen, daher haben wir uns noch keine Container angesehen.
Wenn das Ende der Seite erreicht ist, werden im Absatz Informationen zum Anzeigen von 4 Divs angezeigt.→ Codepen→ GithubEndloses Scrollen
Aufgabe: Implementieren Sie eine endlose Liste.Der Code:let ul = document.querySelector('ul')
let n = 1
function createLi(){
li = document.createElement('li')
li.innerHTML = `${++n} item`
ul.append(li)
}
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
createLi()
}
observer.unobserve(entry.target)
observer.observe(document.querySelector('li:last-child'))
})
}, {
threshold: 1
})
observer.observe(document.querySelector('li'))
Ergebnis:
Wir haben 12 Listenelemente. Das letzte Element befindet sich außerhalb des Ansichtsfensters.
Wenn Sie versuchen, zum letzten Element zu gelangen, wird ein neues (letztes) Element erstellt, das dem Benutzer verborgen bleibt. Und so weiter bis ins Unendliche.→ Codepen→ GithubÄndern der Größe eines Kindes beim Ändern der Größe eines Elternteils
Aufgabe: Bestimmen Sie die Abhängigkeit der Größe eines Elements von einem anderen.Der Code:
let info = document.querySelector('.info')
let parent = document.querySelector('.parent')
let child = document.querySelector('.child')
child.style.width = parent.offsetWidth - 50 + 'px'
info.textContent = `child width: ${child.offsetWidth}px`
let options = {
root: parent,
threshold: 1
}
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if ((entry.target.parentElement.offsetWidth - entry.target.offsetWidth) < 50) {
entry.target.style.width = entry.target.offsetWidth - 50 + 'px'
}
})
}, options)
observer.observe(child)
window.addEventListener('resize', () => {
info.textContent = `child width: ${child.offsetWidth}px`
if ((parent.offsetWidth - child.offsetWidth) > 51) {
child.style.width = child.offsetWidth + 50 + 'px'
}
})
Ergebnis:
Ausgangszustand.
Wenn Sie die Breite des übergeordneten Elements verringern, verringert sich die Breite des untergeordneten Elements. Gleichzeitig beträgt der Abstand zwischen ihnen fast immer 50px („fast“ ist auf die Implementierung des inversen Mechanismus zurückzuführen).→ Codepen→ GithubArbeite mit Animation
Aufgabe: Animieren Sie ein Objekt, wenn es sichtbar ist.Der Code:
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
entry.isIntersecting ? entry.target.classList.replace('to-left', 'to-right') : entry.target.classList.replace('to-right', 'to-left')
})
}, {
threshold: .5
})
observer.observe(document.querySelector('img'))
Ergebnis:
Wir sehen einen Teil von Barts Kopf. Bart drückte sich auf die linke Seite des Sichtbereichs.
Wenn mehr als 50% von Bart in den Sichtbereich fallen, bewegt er sich in die Mitte. Wenn mehr als 50% von Bart den Betrachtungsbereich verlassen, kehrt er in seine Ausgangsposition zurück.→ Codepen→ GithubVielen Dank für Ihre Aufmerksamkeit.