Intersection Observer API-Fallstudien



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 => {
        // entry () - 
        //   entry.boundingClientRect
        //   entry.intersectionRatio
        //   entry.intersectionRect
        //   entry.isIntersecting
        //   entry.rootBounds
        //   entry.target
        //   entry.time
    })
}

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)

    //       img  
    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

→  Github

Bildersatz


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)
                //        "data-src"
                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

→  Github

Containerhintergrund ä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')
    // ratio -   
    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)
    
    //    
    //      20 ,   
    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

→  Github

Arbeite 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()
        //      (   > 0)
        } 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

→  Github

Fortschritt 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')
// n -   
let n = 0

let observer = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
        if(entry.isIntersecting){
            // observer   div
            //       
            //     
            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

→  Github

Endloses 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)
}

//  ,        
//     
//         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')
//     50px  
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 => {
        //         50px
        if ((entry.target.parentElement.offsetWidth - entry.target.offsetWidth) < 50) {
            //     50px
            entry.target.style.width = entry.target.offsetWidth - 50 + 'px'
        }
    })
}, options)

observer.observe(child)

//  ,  ,       IOA
//       resize
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

→  Github

Arbeite 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

→  Github

Vielen Dank für Ihre Aufmerksamkeit.

All Articles