JavaScript obter janela X / Y posição para rolagem

213

Espero encontrar uma maneira de obter a posição atual da janela visível (em relação à largura / altura total da página) para que eu possa usá-la para forçar um deslocamento de uma seção para outra. No entanto, parece haver uma enorme quantidade de opções quando se trata de adivinhar qual objeto contém o verdadeiro X / Y para o seu navegador.

De quais delas preciso para garantir que o IE 6+, FF 2+ e Chrome / Safari funcionem?

window.innerWidth
window.innerHeight
window.pageXOffset
window.pageYOffset
document.documentElement.clientWidth
document.documentElement.clientHeight
document.documentElement.scrollLeft
document.documentElement.scrollTop
document.body.clientWidth
document.body.clientHeight
document.body.scrollLeft
document.body.scrollTop

E existem outros? Depois de saber onde está a janela, posso definir uma cadeia de eventos que será chamada lentamente window.scrollBy(x,y);até atingir o ponto desejado.

Xeoncross
fonte

Respostas:

282

O método que o jQuery (v1.10) usa para encontrar isso é:

var doc = document.documentElement;
var left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
var top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);

Isso é:

  • Ele testa window.pageXOffsetprimeiro e usa isso, se existir.
  • Caso contrário, ele usa document.documentElement.scrollLeft.
  • Em seguida, subtrai document.documentElement.clientLeftse existir.

A subtração de document.documentElement.clientLeft/ Topparece ser necessária para corrigir situações em que você aplicou uma borda (não preenchimento ou margem, mas borda real) ao elemento raiz e, nesse caso, possivelmente apenas em determinados navegadores.

thomasrutter
fonte
Thomas - você está totalmente certo. Foi mal. Comentários removidos. Reli seu comentário e percebi que sua solução não era uma solução Jquery. Desculpas. Modded up.
Bangkokian
Funciona agora. Eu acho que eles tiveram um bug muito temporário no webkit e já o corrigiram. Eu escrevi um plugin completamente quebrado por causa desse bug e os usuários me relataram isso. Muito assustador tais coisas básicas pode quebrar
vsync
2
Esse é o código para $ (window) .scrollTop (); ? Provavelmente seria útil incluir também o método jQuery nesta resposta.
Phil
1
O código que publiquei é uma paráfrase do que se tornou jQuery.fn.offset(). scrollTop()/ scrollLeft()faz basicamente o mesmo, mas não subtraia clientTop / clientLeft.
precisa saber é o seguinte
Qual é o método?
Maxrunner 12/09/16
208

Talvez mais simples;

var top  = window.pageYOffset || document.documentElement.scrollTop,
    left = window.pageXOffset || document.documentElement.scrollLeft;

Créditos: so.dom.js # L492

K-Gun
fonte
1
Perfeitamente cross browser safe! Melhor solução.
Simon Steinberger
1
Isso funcionou melhor do que o código de resposta, mas ... o código de resposta não funcionou, nem um pouco ...
Hydroper
2
Eu me pergunto por que não usar apenas o document.documentElement.scrollTopque funciona em qualquer lugar.
Vsync
33

Usando javascript puro, você pode usar Window.scrollX e Window.scrollY

window.addEventListener("scroll", function(event) {
    var top = this.scrollY,
        left =this.scrollX;
}, false);

Notas

A propriedade pageXOffset é um alias para a propriedade scrollX e a propriedade pageYOffset é um alias para a propriedade scrollY:

window.pageXOffset == window.scrollX; // always true
window.pageYOffset == window.scrollY; // always true

Aqui está uma demonstração rápida

window.addEventListener("scroll", function(event) {
  
    var top = this.scrollY,
        left = this.scrollX;
  
    var horizontalScroll = document.querySelector(".horizontalScroll"),
        verticalScroll = document.querySelector(".verticalScroll");
    
    horizontalScroll.innerHTML = "Scroll X: " + left + "px";
      verticalScroll.innerHTML = "Scroll Y: " + top + "px";
  
}, false);
*{box-sizing: border-box}
:root{height: 200vh;width: 200vw}
.wrapper{
    position: fixed;
    top:20px;
    left:0px;
    width:320px;
    background: black;
    color: green;
    height: 64px;
}
.wrapper div{
    display: inline;
    width: 50%;
    float: left;
    text-align: center;
    line-height: 64px
}
.horizontalScroll{color: orange}
<div class=wrapper>
    <div class=horizontalScroll>Scroll (x,y) to </div>
    <div class=verticalScroll>see me in action</div>
</div>

Gildas.Tambo
fonte
6
A página à qual você vinculou diz "Para compatibilidade entre navegadores, use window.pageYOffset em vez de window.scrollY".
JeremyWeir
Isso não funciona para o IE. O IE requer algo parecido comwindow.pageYOffset
hipkiss
-1
function FastScrollUp()
{
     window.scroll(0,0)
};

function FastScrollDown()
{
     $i = document.documentElement.scrollHeight ; 
     window.scroll(0,$i)
};
 var step = 20;
 var h,t;
 var y = 0;
function SmoothScrollUp()
{
     h = document.documentElement.scrollHeight;
     y += step;
     window.scrollBy(0, -step)
     if(y >= h )
       {clearTimeout(t); y = 0; return;}
     t = setTimeout(function(){SmoothScrollUp()},20);

};


function SmoothScrollDown()
{
     h = document.documentElement.scrollHeight;
     y += step;
     window.scrollBy(0, step)
     if(y >= h )
       {clearTimeout(t); y = 0; return;}
     t = setTimeout(function(){SmoothScrollDown()},20);

}
ali.by
fonte