Javascript: ¿Cómo detectar si la ventana del navegador se desplaza hacia abajo?


187

Necesito detectar si un usuario se desplaza al final de una página. Si están en la parte inferior de la página, cuando agregue contenido nuevo a la parte inferior, los desplazaré automáticamente a la parte inferior nueva. Si no están en la parte inferior, están leyendo el contenido anterior más arriba en la página, por lo que no quiero desplazarlos automáticamente ya que quieren permanecer donde están.

¿Cómo puedo detectar si un usuario se desplaza al final de la página o si se desplaza más arriba en la página?


1
Este se trabajó en Angular 6 -> stackoverflow.com/a/42547136/621951
Günay Gültekin

Respuestas:


268
window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
        // you're at the bottom of the page
    }
};

Ver demo


29
No funciona cuando los elementos html / body están configurados al 100% (para que el cuerpo llene toda la altura de la ventana
gráfica

55
Use en document.documentElement.scrollToplugar de window.scrollYpara IE. No está seguro de lo que, en su caso, las versiones de IE de la ayuda window.scrollY.
Batandwa

3
No funciona en la versión 47.0.2526.73 de Chromium Construida en Ubuntu 14.04, que se ejecuta en el sistema operativo primario 0.3.2 (64 bits)
K - La toxicidad en SO está creciendo.

9
Usé document.body.scrollHeight en lugar de offsetHeight (en mi caso, offsetHeight siempre fue más pequeño que la ventana.innerHeight)
Oliver

1
@KarlMorrison, ¿puedes probar la respuesta premiada (por @Dekel) con tu navegador?
Basj

115

Código actualizado para todos los principales navegadores compatibles (incluye IE10 e IE11)

window.onscroll = function(ev) {
    if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
        alert("you're at the bottom of the page");
    }
};

El problema con la respuesta aceptada actual es que window.scrollY no está disponible en IE.

Aquí hay una cita de mdn con respecto a scrollY:

Para la compatibilidad entre navegadores, use window.pageYOffset en lugar de window.scrollY.

Y un fragmento de trabajo:

Nota para mac

Según el comentario de @ Raphaël, hubo un problema en mac debido a un pequeño desplazamiento.
La siguiente condición actualizada funciona:

(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2

No tuve la oportunidad de probarlo más, si alguien puede comentar sobre este problema específico, será genial.


Confirmado trabajando en FF, Chrome, IE10, Chrome para Android. Gracias @Dekel!
Basj

2
Por extraño que parezca, solo en mi navegador tengo menos de 1 px y, por lo tanto, la condición no se activa. No estoy seguro de por qué, tuve que agregar unos pocos px adicionales para que funcione.
Sharjeel Ahmed

3
en las computadoras Mac, la condición a continuación no se cumple debido a un pequeño desplazamiento (~ 1px) actualizamos la condición así(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2
Raphaël

44
gracias @Dekel! en realidad, descubrimos que window.pageYOffset es un flotante en mac. Nuestra solución final es (window.innerHeight + Math.ceil(window.pageYOffset + 1)) >= document.body.offsetHeight.
Raphaël

2
No funciona para casos en los que el cuerpo tiene un estilo que establece la altura al 100%
raRaRa

56

La respuesta aceptada no funcionó para mí. Esto hizo:

window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
      // you're at the bottom of the page
      console.log("Bottom of page");
    }
};

Si está buscando admitir navegadores antiguos (IE9) use el alias window.pageYOffsetque tiene un soporte ligeramente mejor.


1
no funciona en IE10 / 11. Verifique la respuesta de Dekel ( stackoverflow.com/questions/9439725/… ) para obtener soporte de IE. Trabajó para mí
Herr_Schwabullek

Las otras respuestas activaron el archivo console.log () cada vez que me desplacé, no solo cuando estaba al final de la página. Esta respuesta me funcionó en Chrome.
Defcronyke

Si se deshace de window.scrollY, que no funciona en ie o edge, esta es una respuesta decente. Reemplace con: (window.innerHeight + window.pageYOffset)> = document.body.scrollHeight
colemerrick

21

Estaba buscando una respuesta pero no encontré una exacta. Aquí hay una solución javascript pura que funciona con las últimas versiones de Firefox, IE y Chrome en el momento de esta respuesta:

// document.body.scrollTop alone should do the job but that actually works only in case of Chrome.
// With IE and Firefox it also works sometimes (seemingly with very simple pages where you have
// only a <pre> or something like that) but I don't know when. This hack seems to work always.
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;

// Grodriguez's fix for scrollHeight:
// accounting for cases where html/body are set to height:100%
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;

// >= is needed because if the horizontal scrollbar is visible then window.innerHeight includes
// it and in that case the left side of the equation is somewhat greater.
var scrolledToBottom = (scrollTop + window.innerHeight) >= scrollHeight;

// As a bonus: how to scroll to the bottom programmatically by keeping the horizontal scrollpos:
// Since window.innerHeight includes the height of the horizontal scrollbar when it is visible
// the correct vertical scrollTop would be
// scrollHeight-window.innerHeight+sizeof(horizontal_scrollbar)
// Since we don't know the visibility/size of the horizontal scrollbar
// we scroll to scrollHeight that exceeds the value of the
// desired scrollTop but it seems to scroll to the bottom with all browsers
// without problems even when the horizontal scrollbar is visible.
var scrollLeft = (document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft;
window.scrollTo(scrollLeft, scrollHeight);

44
Esto casi funcionó para mí, pero tuve que usar en ((document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight)lugar de solo document.body.scrollHeightpara tener en cuenta los casos en que html / body están configurados en altura: 100%
Grodriguez

1
@Grodriguez ¡Gracias por la información! ¡Puede ser útil para nosotros en el futuro! :-)
pasztorpisti

15

Esto funciona

window.onscroll = function() {

    // @var int totalPageHeight
    var totalPageHeight = document.body.scrollHeight; 

    // @var int scrollPoint
    var scrollPoint = window.scrollY + window.innerHeight;

    // check if we hit the bottom of the page
    if(scrollPoint >= totalPageHeight)
    {
        console.log("at the bottom");
    }
}

Si está buscando admitir navegadores antiguos (IE9), reemplace window.scrollY con window.pageYOffset


1
este trabajo reacciona en 2019. trabaja con cuerpo 100% de altura, vale la pena con html 100% de altura. trabajar con chrome, safari, firefox, edge.
Kiwi enojado

Solo una nota: los nombres deben cambiarse, las variables deben cambiarse. Debido a que scrollHeight muestra la altura total de la página, y totalHeight muestra el punto de desplazamiento actual, por lo que es un poco confuso.
Vladimir Marton

4

Acabo de empezar a mirar esto y las respuestas aquí me ayudaron, así que gracias por eso. Me he expandido un poco para que el código esté seguro hasta IE7:

Espero que esto sea útil para alguien.

Aquí, tiene un violín;)

    <!DOCTYPE html>
<html>
<head>
    <style>
        div {
            height: 100px;
            border-bottom: 1px solid #ddd;
        }

        div:nth-child(even) {
            background: #CCC
        }

        div:nth-child(odd) {
            background: #FFF
        }

    </style>
</head>

<body>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</body>

<script type="text/javascript">
console.log("Doc Height = " + document.body.offsetHeight);
console.log("win Height = " + document.documentElement.clientHeight);
window.onscroll = function (ev) {
    var docHeight = document.body.offsetHeight;
    docHeight = docHeight == undefined ? window.document.documentElement.scrollHeight : docHeight;

    var winheight = window.innerHeight;
    winheight = winheight == undefined ? document.documentElement.clientHeight : winheight;

    var scrollpoint = window.scrollY;
    scrollpoint = scrollpoint == undefined ? window.document.documentElement.scrollTop : scrollpoint;

    if ((scrollpoint + winheight) >= docHeight) {
        alert("you're at the bottom");
    }
};
</script>
</html>

Tipo de obras. Pero no es muy preciso. Considera que se desplaza hacia abajo siempre que esté dentro de unos 16 píxeles del fondo.
Peter Hall

4

Si está configurando height: 100%un contenedor <div id="wrapper">, el siguiente código funciona (probado en Chrome):

var wrapper = document.getElementById('wrapper');

wrapper.onscroll = function (evt) {
  if (wrapper.scrollTop + window.innerHeight >= wrapper.scrollHeight) {
    console.log('reached bottom!');
  }
}

3
window.onscroll = function(ev) {
    if ((window.innerHeight + Math.ceil(window.pageYOffset)) >= document.body.offsetHeight) {
        alert("you're at the bottom of the page");
    }
};

Esta respuesta solucionará casos extremos, esto es porque pageYOffsetes doublewhile innerHeighty offsetHeightarelong , por lo que cuando el navegador le brinda la información, es posible que le falte un píxel. Por ejemplo: en la parte inferior de la página tenemos

cierto window.innerHeight = 10.2

cierto window.pageYOffset = 5.4

cierto document.body.offsetHeight = 15.6

Nuestro cálculo se convierte en: 10 + 5.4> = 16 que es falso

Para solucionar esto podemos hacer Math.ceilen el pageYOffsetvalor.

Espero que ayude.


3

si amas a jquery

$(window).scroll(function() {
  if($(window).scrollTop() + $(window).height() >= $(document).height()) {
    // doSomethingHere();
  }
});

Y quién no ama jQuery ...
Josh Habdas

2
Navegadores @JoshHabdas
Toni Michel Caubet

2

Puedes mirar el desplazamiento infinito de jquery:

http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/

Parece que hace lo que está pidiendo, suponiendo que esté dispuesto a usar la biblioteca jquery y sin esperar un estricto método JS puro.


2
Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden volverse inválidas si la página vinculada cambia.
bobthedeveloper

@Hatsjoem Él está vinculando a un complemento. ¿Cuáles son exactamente las "partes esenciales" que deben copiarse? ¿A quién le importa si la respuesta "se invalida si la página vinculada cambia"? Si el enlace se rompe, eso significa que el complemento se suspendió y ya no existe, incluso si agrega más información a la respuesta, sería aún no será válido. Por Dios, las respuestas de solo enlace no son necesariamente malas.
dcastro

@Hatsjoem También, de meta : "Cuando la biblioteca a la que se hace referencia está en una ubicación estable y bien conocida, este tipo de respuesta es generalmente una respuesta pobre pero una respuesta : dice" usa esto ".
dcastro

Además, probablemente Google seguirá existiendo si el desplazamiento infinito cambia esta URL. El punto es usar ese complemento, por lo que si el enlace muere, solo busque en google jquery infinite scroll. Probablemente encontrarás lo que necesitas.
Kai Qing

2

Sorprendentemente, ninguna de las soluciones funcionó para mí. Creo que es porque mi cssestaba en mal estado y bodyno envolvía todo el contenido cuando lo usaba height: 100%(todavía no sé por qué). Sin embargo, mientras buscaba una solución, se me ocurrió algo bien ... básicamente lo mismo, pero tal vez valga la pena mirarlo: soy nuevo en la programación, así que lo siento si está haciendo lo mismo más lento, es menos compatible o algo así ese...

window.onscroll = function(evt) {
  var check = (Element.getBoundingClientRect().bottom - window.innerHeight <= 0) ? true : false;
  if (check) { console.log("You're at the bottom!"); }
};

2
$(document).ready(function(){
    $('.NameOfYourDiv').on('scroll',chk_scroll);
});

function chk_scroll(e)
{
    var elem = $(e.currentTarget);
    if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) 
    {
        alert("scrolled to the bottom");
    }

}

Idk una perspectiva diferente. Pero la respuesta aceptada es mejor con seguridad
Zihan Zhang

2
const handleScroll = () => {
    if (Math.round(window.scrollY + window.innerHeight) >= Math.round(document.body.scrollHeight)) {
        onScroll();
    }
};

Este código también funcionó para mí en Firefox e IE.


1

Uso defaultViewy documentElementcon fragmento de código funcional incrustado:

const { defaultView } = document;
const { documentElement } = document;
const handler = evt => requestAnimationFrame(() => {
  const hitBottom = (() => (defaultView.innerHeight + defaultView.pageYOffset) >= documentElement.offsetHeight)();
  hitBottom
    ? console.log('yep')
    : console.log('nope')
});
document.addEventListener('scroll', handler);
<pre style="height:110vh;background-color:fuchsia">scroll down</pre>


1

Puede verificar si el resultado combinado de la altura de la ventana y la parte superior de desplazamiento es mayor que el del cuerpo

if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {}


0

Tuve que encontrar una forma (en Java) de desplazarme sistemáticamente hacia abajo en busca de un componente para el que no conocía el XPath correcto (historia larga, así que solo sigue el juego). Como acabo de decir, necesitaba desplazarme hacia abajo mientras buscaba un componente y detenerme cuando se encontraba el componente o se llegaba al final de la página.

El siguiente fragmento de código controla el desplazamiento hacia la parte inferior de la página:

JavascriptExecutor js = (JavascriptExecutor) driver;
boolean found = false;
long currOffset = 0;
long oldOffset = 0;
do
{
    oldOffset = currOffset;
    // LOOP to seek the component using several xpath regexes removed
    js.executeScript("window.scrollBy(0, 100)");
    currOffset = (Long)js.executeScript("var offset = window.window.pageYOffset; return offset;");
} while (!found && (currOffset != oldOffset));

Por cierto, la ventana se maximiza antes de que se ejecute este fragmento de código.


0

La respuesta aceptada no funcionó para mí. Esto hizo:

const element = document.createElement('div');
document.body.appendChild(element);
document.addEventListener('scroll', () => {
    const viewportHeight = window.innerHeight;
    const distance = element.getBoundingClientRect().top;
    if (Math.floor(distance) <= viewportHeight) {
        console.log('yep')
    } else {
        console.log('nope')
    }
})

0

Encontré dos soluciones que me funcionaron:

  window.addEventListener('scroll', function(e) {
    if (
      window.innerHeight + document.documentElement.scrollTop ===
      document.documentElement.offsetHeight
    ) {
      console.log('You are at the bottom')
    }
  })

Y el otro:

  window.addEventListener('scroll', function(e) {
    if (
      window.innerHeight + window.pageYOffset ===
      document.documentElement.offsetHeight
    ) {
      console.log('You are at the bottom')
    }
  })
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.