Ci sono oltre 30 risposte a questa domanda, e nessuna di esse utilizza la soluzione JS incredibilmente semplice e pura che ho usato. Non è necessario caricare jQuery solo per risolvere questo problema, come molti altri stanno spingendo.
Per sapere se l'elemento è all'interno del viewport, dobbiamo prima determinare la posizione degli elementi all'interno del corpo. Non abbiamo bisogno di farlo in modo ricorsivo come pensavo una volta. Invece, possiamo usare element.getBoundingClientRect()
.
pos = elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top;
Questo valore è la differenza Y tra la parte superiore dell'oggetto e la parte superiore del corpo.
Dobbiamo quindi dire se l'elemento è visibile. La maggior parte delle implementazioni chiede se l'intero elemento sia all'interno del viewport, quindi questo è ciò che tratteremo.
Prima di tutto, la posizione superiore della finestra è: window.scrollY
.
Possiamo ottenere la posizione inferiore della finestra aggiungendo l'altezza della finestra nella sua posizione superiore:
var window_bottom_position = window.scrollY + window.innerHeight;
Consente di creare una semplice funzione per ottenere la posizione più alta dell'elemento:
function getElementWindowTop(elem){
return elem && typeof elem.getBoundingClientRect === 'function' ? elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top : 0;
}
Questa funzione restituirà la posizione più alta dell'elemento all'interno della finestra o ritornerà 0
se gli passi qualcosa di diverso da un elemento con il simbolo.getBoundingClientRect()
metodo. Questo metodo esiste da molto tempo, quindi non dovresti preoccuparti che il tuo browser non lo supporti.
Ora, la posizione più alta del nostro elemento è:
var element_top_position = getElementWindowTop(element);
E la posizione in basso dell'elemento è:
var element_bottom_position = element_top_position + element.clientHeight;
Ora possiamo determinare se l'elemento è all'interno della finestra controllando se la posizione inferiore dell'elemento è inferiore alla posizione superiore della finestra e controllando se la posizione superiore dell'elemento è più alta della posizione inferiore della finestra:
if(element_bottom_position >= window.scrollY
&& element_top_position <= window_bottom_position){
//element is in view
else
//element is not in view
Da lì, puoi eseguire la logica per aggiungere o rimuovere una in-view
classe sul tuo elemento, che puoi successivamente gestire con effetti di transizione nel tuo CSS.
Sono assolutamente sorpreso di non aver trovato questa soluzione altrove, ma credo che questa sia la soluzione più pulita ed efficace e non richieda il caricamento di jQuery!