Hay más de 30 respuestas a esta pregunta, y ninguna de ellas utiliza la solución JS increíblemente simple y pura que he estado usando. No es necesario cargar jQuery solo para resolver esto, ya que muchos otros están presionando.
Para saber si el elemento está dentro de la ventana gráfica, primero debemos determinar la posición de los elementos dentro del cuerpo. No necesitamos hacer esto de forma recursiva como alguna vez pensé. En cambio, podemos usar element.getBoundingClientRect()
.
pos = elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top;
Este valor es la diferencia Y entre la parte superior del objeto y la parte superior del cuerpo.
Entonces debemos decir si el elemento está a la vista. La mayoría de las implementaciones preguntan si el elemento completo está dentro de la ventana gráfica, por lo que esto es lo que cubriremos.
En primer lugar, la posición superior de la ventana es: window.scrollY
.
Podemos obtener la posición inferior de la ventana agregando la altura de la ventana a su posición superior:
var window_bottom_position = window.scrollY + window.innerHeight;
Vamos a crear una función simple para obtener la posición superior del elemento:
function getElementWindowTop(elem){
return elem && typeof elem.getBoundingClientRect === 'function' ? elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top : 0;
}
Esta función devolverá la posición superior del elemento dentro de la ventana o volverá 0
si le pasa algo más que un elemento con el .getBoundingClientRect()
método. Este método ha existido durante mucho tiempo, por lo que no debería tener que preocuparse de que su navegador no lo admita.
Ahora, la posición superior de nuestro elemento es:
var element_top_position = getElementWindowTop(element);
Y la posición inferior del elemento es:
var element_bottom_position = element_top_position + element.clientHeight;
Ahora podemos determinar si el elemento está dentro de la ventana gráfica al verificar si la posición inferior del elemento es más baja que la posición superior de la ventana gráfica y al verificar si la posición superior del elemento es más alta que la posición inferior de la ventana gráfica:
if(element_bottom_position >= window.scrollY
&& element_top_position <= window_bottom_position){
//element is in view
else
//element is not in view
A partir de ahí, puede realizar la lógica para agregar o eliminar una in-view
clase en su elemento, que luego puede manejar con efectos de transición en su CSS.
Estoy absolutamente asombrado de no haber encontrado esta solución en ningún otro lado, pero sí creo que es la solución más limpia y efectiva, ¡y no requiere que cargue jQuery!