Como obter e definir a posição de rolagem da página da web atual?

121

Como posso obter e definir a posição atual de rolagem da página da web?

Tenho um formulário longo que precisa ser atualizado com base nas ações / entradas do usuário. Quando isso acontece, a página é redefinida para o topo, o que é irritante para os usuários, porque eles precisam rolar para baixo até o ponto em que estavam.

Se eu pudesse capturar a posição de rolagem atual (em uma entrada oculta) antes de recarregar a página, poderia configurá-la novamente depois de recarregar.

xyz
fonte
Um formulário orientado a AJAX não é a melhor maneira de evitar esses efeitos (e, claro, fornecer um fallback caso o XHR não esteja disponível)? Recarregar páginas fará com que a página pule para o topo e volte novamente, uma peculiaridade que pode ser irritante.
Marcel Korpel

Respostas:

118

Você está procurando a document.documentElement.scrollToppropriedade.

SLaks
fonte
obrigado, encontrei este: articles.sitepoint.com/article/javascript-from-scratch/6 e modifiquei o getScrollingPosition()para armazenar os valores em variáveis ​​ocultas. Então, no html da página atualizada que uso <body onLoad="window.scrollTo(x,y), onde x e y são os valores dos valores ocultos!
xyz
46
Estou descobrindo, pelo menos no Chrome no Ubuntu, que document.documentElement.scrollTopsempre retorna 0. document.body.scrollTop, no entanto, parece funcionar. Um Firefox no Ubuntu, por outro lado, o inverso é verdadeiro - você obtém 0 com bodye a quantidade correta com documentElement. Alguma ideia do que dá?
tobek
12
Esta resposta não é precisa, pois a scrollToppropriedade não funciona em todos os navegadores. Verifique window.pageXOffsete window.pageYOffsetpara melhores resultados.
gyo
135

A resposta aceita atualmente está incorreta - document.documentElement.scrollTopsempre retorna 0 no Chrome. Isso ocorre porque o WebKit usa bodypara controlar a rolagem, enquanto o Firefox e o IE usam html.

Para obter a posição atual, você deseja:

document.documentElement.scrollTop || document.body.scrollTop

Você pode definir a posição atual para 1000 px na página, desta forma:

document.documentElement.scrollTop = document.body.scrollTop = 1000;

Ou, usando jQuery (anime enquanto você está nisso!):

$("html, body").animate({ scrollTop: "1000px" });
tobek
fonte
5
resposta do gyo, sugerindo que window.pageYOffseté mais limpo se você estiver usando métodos window.scrollBy()ou window.scrollTo().
igorsantos07
32

Existem algumas inconsistências em como os navegadores expõem as coordenadas de rolagem da janela atual. O Google Chrome no Mac e iOS parece sempre retornar 0ao usar document.documentElement.scrollTopou jQuery $(window).scrollTop().

No entanto, funciona de forma consistente com:

// horizontal scrolling amount
window.pageXOffset

// vertical scrolling amount
window.pageYOffset
gyo
fonte
Eu também percebi, é um bug no Mac e iOS?
Alexander Kim
@AlexanderKim Acho que pode estar relacionado a como certas regras CSS (como overflow) são interpretadas, e foi relatado que funciona ao verificar scrollTop nos elementos body e html. No entanto, para evitar testes e depuração, sempre confio no pageXOffset / pageYOffset seguro e consistente.
gyo
muito obrigado pela resposta correta
Michael Paccione
5

Eu optei pela solução de armazenamento local HTML5 ... Todos os meus links chamam uma função que define isso antes de alterar window.location:

localStorage.topper = document.body.scrollTop;

e cada página tem isso no onLoad do corpo:

  if(localStorage.topper > 0){ 
    window.scrollTo(0,localStorage.topper);
  }
AX Labs
fonte
3
Seria mais elegante usar setItem () e getItem () de localStorage e, em vez disso, fazer backup da posição de rolagem a cada clique no link, armazene-a uma vez ao sair da página: window.addEventListener ("beforeunload", function () {localStorage. setItem ("scrolly", document.documentElement.scrollTop || document.body.scrollTop);});
StanE