jQuery / Método / .scrollTop() - Ler ou definir a posição vertical
No jQuery, .scrollTop() lê a posição vertical atual do primeiro alvo e .scrollTop(120) define em todos. Selecione $(window) para a página ou o elemento para um contêiner interno. Isso não lê a posição do elemento no documento.
Escolher o alvo da rolagem
A API de .scrollTop() mede conteúdo oculto acima em pixels CSS. No fluxo normal de cima para baixo, zero é o início e o valor aumenta para baixo. Não é a coordenada visual do indicador da barra nem CSS top.
| Tarefa | Alvo e chamada | Condição |
|---|---|---|
| Ler a página | $(window).scrollTop() | Documento mais alto que a área visível |
| Mover caixa para 120px | $("#box").scrollTop(120) | Altura limitada e conteúdo excedente |
| Voltar ao início | alvo.scrollTop(0) | Alvo que realmente rola |
As leituras nativas são Element.scrollTop e window.scrollY. Aqui o jQuery usa um método para ambos. Ler não move a visualização.
Exemplo completo de página e caixa
Salve todo o código em UTF-8 como scroll-demo.html e abra no navegador. É preciso Internet para o arquivo oficial do jQuery 4.0.0 da rede de distribuição de conteúdo (CDN), sem instalação. Posições, pedidos excessivos, restauração e Console foram executados com 3.7.1 e 4.0.0 no Edge para Windows.
O documento tem pelo menos 2000px, e a caixa fica em top 500px. Seis linhas de 100px produzem 600px de conteúdo com 160px internos visíveis: máximo 600 - 160 = 440px. Bordas ficam fora dessa altura. scroll-behavior:auto permite comparação direta.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Separate page and element scroll positions</title>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<style>
html { scroll-behavior: auto; }
body { margin: 0; min-height: 2000px; font: 16px/1.6 sans-serif; }
#controls { position: fixed; top: 0; left: 0; right: 0; z-index: 2; background: #fff; padding: 12px; max-height: 42vh; overflow: auto; }
button { font: inherit; margin: 3px; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
#box { position: absolute; top: 500px; left: 20px; right: 20px; max-width: 600px; height: 160px; overflow-y: auto; border: 2px solid teal; scroll-behavior: auto; }
.row { height: 100px; box-sizing: border-box; padding: 12px; border-bottom: 1px solid #abc; background: #edf9f6; }
</style>
</head>
<body>
<div id="controls">
<strong>Page and box scrolling</strong>
<button type="button" id="box120">Box to 120</button>
<button type="button" id="bottom">Box to bottom</button>
<button type="button" id="page300">Page to 300</button>
<button type="button" id="reset">Reset both</button>
<pre id="result" aria-live="polite"></pre>
</div>
<div id="box" tabindex="0" aria-label="Scrollable example rows">
<div class="row">Alpha</div><div class="row">Beta</div><div class="row">Gamma</div><div class="row">Delta</div><div class="row">Epsilon</div><div class="row">Zeta</div>
</div>
<script>
$(function () {
const $box = $("#box");
function report() {
const node = $box.get(0);
const top = $box.scrollTop();
const max = Math.max(0, node.scrollHeight - node.clientHeight);
const bottom = max > 0 && Math.abs(max - top) <= 1;
$("#result").text(`window=${$(window).scrollTop()}\nbox=${top}\nbox max=${max}\nat bottom=${bottom}`);
}
$("#box120").on("click", function () { $box.scrollTop(120); report(); });
$("#bottom").on("click", function () { $box.scrollTop(1000000); report(); });
$("#page300").on("click", function () { $(window).scrollTop(300); report(); });
$("#reset").on("click", function () { $box.scrollTop(0); $(window).scrollTop(0); report(); });
$box.on("scroll.scrollLesson", report);
$(window).on("scroll.scrollLesson resize.scrollLesson", report);
report();
});
</script>
</body>
</html>
A saída pressupõe ambos no início. Se a área visível superar 2000px e a página não transbordar, reduza sua altura para testar.
window=0
box=0
box max=440
at bottom=false
- Box to 120 dá box=120 e mantém window=0. Parte de Alpha fica oculta acima.
- Page to 300 dá window=300, box=120. Mover a caixa na tela difere de mover seu conteúdo.
- Box to bottom pede 1000000, mas esta caixa normal limita a 440. at bottom vira true.
- Role diretamente ou use o teclado dentro da caixa para atualizar seu evento scroll. Os controles fixos mantêm as leituras acessíveis.
- Reset both retorna caixa e janela separadamente a zero, mesmo ao repetir.
Registre scroll diretamente no elemento que rola. window scroll não trata automaticamente a caixa interna. report() lê ambas as posições e recalcula o máximo.
Máximo, final e vários elementos
Em uma caixa vertical normal, o máximo é Math.max(0, scrollHeight - clientHeight). scrollHeight mede conteúdo e clientHeight o interior visível. O exemplo exige máximo positivo e diferença de até 1px para indicar o final, sem igualdade exata diante de possíveis frações.
Sem transbordamento, o pedido pode manter zero. Aqui at bottom fica false; considerar uma caixa curta já no final depende da interface. Imagens, fontes e dimensões podem mudar altura e máximo.
Execute isto no Console da mesma página. Duas caixas temporárias recebem posições diferentes. Consultar a coleção lê só a primeira; definir 80 altera ambas. A área temporária é removida depois.
const $holder = $("<div>").appendTo("body");
const $boxes = $("<div></div><div></div>").css({ height: 40, overflowY: "auto" }).appendTo($holder);
$boxes.each(function () { $(this).append($("<div>").css("height", 200)); });
$boxes.eq(0).scrollTop(40);
$boxes.eq(1).scrollTop(100);
console.log(`first getter=${$boxes.scrollTop()}`);
$boxes.scrollTop(80);
console.log(`all=${$boxes.map(function () { return $(this).scrollTop(); }).get().join(",")}`);
console.log(`empty getter=${typeof $().scrollTop()}`);
$holder.remove();
first getter=40
all=80,80
empty getter=undefined
Uma seleção vazia retorna undefined. Zero é posição válida, não ausência de alvo. Confira .length, o elemento que rola e a preparação do modelo de objetos do documento (DOM).
Investigar falta de movimento ou valores diferentes
overflow-y:auto não basta se a caixa cresce com o conteúdo. Confira altura ou altura máxima e scrollHeight/clientHeight. Se um ancestral rola, mas você seleciona o filho, este pode continuar em zero.
Use window para diferenciar página e contêineres. Definir um número não pede sozinho uma animação temporizada do jQuery. CSS de rolagem suave ou outros efeitos podem mudar o tempo: não trate leitura intermediária como resultado final.
Nem todos os valores são inteiros ou não negativos. A MDN descreve frações, valores negativos com column-reverse e ultrapassagem dos limites no Safari. O intervalo verificado 0–440 pertence a esta caixa normal no Edge. Em outros layouts, confira direção e comportamento do navegador.




