¿Cómo obtener la posición de la barra de desplazamiento con Javascript?

191

Estoy tratando de detectar la posición de la barra de desplazamiento del navegador con JavaScript para decidir en qué parte de la página se encuentra la vista actual. Supongo que tengo que detectar dónde está el pulgar en la pista, y luego la altura del pulgar como un porcentaje de la altura total de la pista. ¿Lo estoy complicando demasiado o JavaScript ofrece una solución más fácil que esa? ¿Alguna idea de código sabio?

Pablo
fuente

Respuestas:

210

Puede usar element.scrollTopy element.scrollLeftpara obtener el desplazamiento vertical y horizontal, respectivamente, que se ha desplazado. elementpuede ser document.bodysi te importa toda la página. Puede compararlo con element.offsetHeighty element.offsetWidth(nuevamente, elementpuede ser el cuerpo) si necesita porcentajes.

Max Shawabkeh
fuente
2
¿Qué navegador estás usando? Obtener el cuerpo se realiza de manera diferente en diferentes navegadores ( elementy document.bodyeran solo ejemplos). Vea howtocreate.co.uk/tutorials/javascript/browserwindow para más detalles.
Max Shawabkeh
8
Lo conseguí para darme el valor correcto en Firefox 3.6 con window.pageYOffset, pero no puedo hacer que nada funcione en IE7. Intentado window.pageYOffset, document.body.scrollTop, document.documentElement.scrollTop,element.scrollTop
Paul
1
scrollTop solo funcionó para mí cuando agregué corchetes ... $ (". scrollBody"). scrollTop ()
maia
9
Si está tratando con el Elemento 'ventana', puede usar window.scrollY en lugar de window.scrollTop
Janis Jansen
66
Creo que la posición de desplazamiento no está activada document.bodyen la mayoría de los navegadores modernos, generalmente está activada document.documentElementahora. Consulte bugs.chromium.org/p/chromium/issues/detail?id=157855 para la transición de Chrome.
fzzfzzfzz
134

Lo hice por un <div>en Chrome.

element .scrollTop : son los píxeles ocultos en la parte superior debido al desplazamiento. Sin desplazamiento, su valor es 0.

elemento .scrollHeight : son los píxeles de todo el div.

element .clientHeight : son los píxeles que ve en su navegador.

var a = element.scrollTop;

Será el puesto.

var b = element.scrollHeight - element.clientHeight;

será el valor máximo para scrollTop .

var c = a / b;

será el porcentaje de desplazamiento [de 0 a 1] .

Gatsby
fuente
3
Esto es casi correcto. para var b deberías restar window.innerHeight no element.clientHeight.
Kahless
51
document.getScroll = function() {
    if (window.pageYOffset != undefined) {
        return [pageXOffset, pageYOffset];
    } else {
        var sx, sy, d = document,
            r = d.documentElement,
            b = d.body;
        sx = r.scrollLeft || b.scrollLeft || 0;
        sy = r.scrollTop || b.scrollTop || 0;
        return [sx, sy];
    }
}

devuelve una matriz con dos enteros: [scrollLeft, scrollTop]

Kennebec
fuente
44
Mostrar cómo usar esta función con un ejemplo hubiera sido genial.
user18490
1
Supongo que puedes usar esto lastscroll = getScroll (); window.scrollTo (lastscroll [0], lastscroll [1]);
Dinesh Rajan
Funciona muy bien, pero cambié el retorno a un objeto con las teclas x e y ya que eso tiene un poco más de sentido para mí.
xd6_
Editado siguiendo el comentario de @ user18490.
Davide Cannizzo
ReferenceError: No se puede encontrar la variable: elemento
Jonny
33

Es como esto :)

window.addEventListener("scroll", function (event) {
    var scroll = this.scrollY;
    console.log(scroll)
});
Pastor Brayan
fuente
12

Respuesta para 2018 :

La mejor manera de hacer cosas así es usar la API Intersection Observer .

La API Intersection Observer proporciona una manera de observar asincrónicamente los cambios en la intersección de un elemento de destino con un elemento ancestro o con la ventana de un documento de nivel superior.

Históricamente, detectar la visibilidad de un elemento, o la visibilidad relativa de dos elementos en relación entre sí, ha sido una tarea difícil para la que las soluciones no han sido confiables y propensas a hacer que el navegador y los sitios a los que accede el usuario se vuelvan lentos. Desafortunadamente, a medida que la web ha madurado, la necesidad de este tipo de información ha crecido. La información de intersección es necesaria por muchas razones, tales como:

  • Desplazamiento lento de imágenes u otro contenido a medida que se desplaza una página.
  • Implementación de sitios web de "desplazamiento infinito", donde cada vez se carga más contenido y se procesa a medida que se desplaza, para que el usuario no tenga que pasar las páginas.
  • Informe de visibilidad de anuncios para calcular los ingresos publicitarios.
  • Decidir si realizar o no tareas o procesos de animación en función de si el usuario verá o no el resultado.

La implementación de la detección de intersecciones en el pasado involucraba controladores de eventos y métodos de llamada de bucles como Element.getBoundingClientRect () para generar la información necesaria para cada elemento afectado. Dado que todo este código se ejecuta en el hilo principal, incluso uno de estos puede causar problemas de rendimiento. Cuando un sitio se carga con estas pruebas, las cosas pueden ponerse completamente feas.

Vea el siguiente código de ejemplo:

var options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

var observer = new IntersectionObserver(callback, options);

var target = document.querySelector('#listItem');
observer.observe(target);

La mayoría de los navegadores modernos admiten IntersectionObserver , pero debe usar el polyfill para compatibilidad con versiones anteriores.

str
fuente
8

si te importa toda la página. puedes usar esto:

document.body.getBoundingClientRect().top

lemospy
fuente
1
use document.body en su lugar
danial dezfouli
3

Si está utilizando jQuery, existe una función perfecta para usted: .scrollTop ()

Doc aquí -> http://api.jquery.com/scrollTop/

nota: puede usar esta función para recuperar O establecer la posición.

ver también: http://api.jquery.com/?s=scroll

Simón el salmón
fuente
25
¿Por qué responder una pregunta sobre JS con una biblioteca para JS, cuando es completamente posible e incluso conveniente hacerlo en JS sin formato? Solo le está pidiendo que agregue tiempo de carga adicional y que use algo de almacenamiento para algo completamente innecesario. Además, ¿desde cuándo JavaScript comenzó a significar JQuery?
DaemonOfTheWest
44
si preguntas individualmente, nunca me gustó jQuery y no he respondido a esta pregunta, pero en Vanilla JS ya hay respuestas dadas por otros compañeros, entonces, ¿cuál es el problema si alguien ha agregado una especia sabrosa en este hilo? (Él ya mencionó que si estás usando jQuery)
Ravinder Payal
@ R01010010 es porque hoy en día JQuery es inútil y contraproducente, todas las funciones de JQuery se implementan fácilmente con VanilaJS, también depende de lo que hay dentro de JQuery, con nuevas funciones disponibles en VanillsaJS, usted como programador, no se actualizará, solo como ejemplo , ahora hay una nueva API en VanillaJS llamada fetch que reemplazó a la antigua XHR, si solo estuvieras en el mundo de JQuery nunca verás los beneficios de fetch y continuarás usando jQuery.ajax (). Mi opinión personal es que las personas que continúan usando JQuery es porque dejaron de aprender. También VanillaJS es más rápido vanilla-js.com
John Balvin Arias
@JohnBalvinArias hablando de fetch, ¿qué pasa con ie11 o incluso Edge?
Ben
Corrígeme si me equivoco, pero fetch no funciona correctamente en "moderno", es decir, y todavía se usa ampliamente. Si estuviera usando jquery, difícilmente me animaría a seguir adelante
Ben
3

Aquí está la otra forma de obtener la posición de desplazamiento

const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
Gor
fuente
0

Creo que la siguiente función puede ayudar a tener valores de coordenadas de desplazamiento:

const getScrollCoordinate = (el = window) => ({
  x: el.pageXOffset || el.scrollLeft,
  y: el.pageYOffset || el.scrollTop,
});

Tengo esta idea de esta respuesta con un pequeño cambio.

AmerllicA
fuente