Como obter a altura de todo o documento com JavaScript?

333

Alguns documentos não podem ter a altura do documento (para posicionar algo absolutamente na parte inferior). Além disso, um fundo de preenchimento parece não fazer nada nessas páginas, mas sim nas páginas em que a altura retornará. Caso (s) em questão:

http://fandango.com
http://paperbackswap.com

No Fandango, o
jQuery $(document).height();retorna o valor correto
document.heightretorna 0
document.body.scrollHeightretorna 0

Na troca de brochura:
TypeError do jQuery $(document).height();: $(document)is null
document.heightretorna um valor incorreto
document.body.scrollHeightretorna um valor incorreto

Nota: Eu tenho permissões no nível do navegador, se houver algum truque lá.

Nic
fonte
5
$ (document) é nulo porque esse site não possui o jQuery carregado ... #
James
Hm, poderia jurar que verifiquei outra coisa para confirmar se o jQuery foi registrado, mas não parece que eu fiz, HA! Eu pensei que o firebug tinha o jQuery empacotado ... hm, acho que vou verificar isso se for uma solução.
1774
4
O firebug não possui o jQUery empacotado
harsimranb
Consulte Localizando o tamanho da janela do navegador . Possui uma excelente tabela de comportamentos de diferentes navegadores.
Oriol

Respostas:

670

Os tamanhos dos documentos são um pesadelo para a compatibilidade do navegador, porque, embora todos os navegadores exponham as propriedades clientHeight e scrollHeight, nem todos concordam como os valores são calculados.

Costumava haver uma fórmula complexa de práticas recomendadas sobre como você testou a altura / largura corretas. Isso envolvia o uso das propriedades document.documentElement, se disponíveis, ou o retorno às propriedades do documento e assim por diante.

A maneira mais simples de obter a altura correta é obter todos os valores de altura encontrados no documento ou documentElement e usar o mais alto. Isto é basicamente o que o jQuery faz:

var body = document.body,
    html = document.documentElement;

var height = Math.max( body.scrollHeight, body.offsetHeight, 
                       html.clientHeight, html.scrollHeight, html.offsetHeight );

Um teste rápido com o bookmarklet Firebug + jQuery retorna a altura correta para ambas as páginas citadas, assim como o exemplo de código.

Observe que testar a altura do documento antes que ele esteja pronto sempre resultará em 0. Além disso, se você carregar mais itens ou o usuário redimensionar a janela, poderá ser necessário testá-lo novamente. Use onloadou um evento pronto para documento , se você precisar disso no momento do carregamento, caso contrário, teste sempre que precisar do número.

Borgar
fonte
2
avaliar esta solução, porque ele funciona quando você está usando a biblioteca de protótipo, com jQuery não existe tal problema
se_pavel
10
Ao trabalhar com iframes e jquery, devido a esse método de cálculo, a altura do documento do iframe sempre será pelo menos a altura do próprio iframet. É importante observar quando você deseja reduzir a altura do iframe para corresponder ao conteúdo. Você primeiro precisa redefinir a altura do iframe.
David Lay
3
Eu tive a necessidade de aumentar o iframe e reduzi-lo (aplicativo do facebook) e descobri que document.body.offsetHeight era a melhor escolha para mim, com suporte preciso da maioria dos navegadores.
JeffG
11
Isso é ótimo, embora possa dar resultados incorretos se o documento não está pronto - ou seja, quando usado no código do servidor gerado ...
stuartdotnet
11
Testar o documento antes de estar pronto não funcionará. Isso não tem nada a ver com o código / documentos gerados, mas como o documento é carregado. O teste deve ser executado depois que o documento estiver pronto, e eu sugiro executá-lo somente quando o documento estiver totalmente carregado, pois os itens restantes podem afetar a altura, também redimensionando o navegador.
Borgar
212

Esta é uma pergunta muito antiga e, portanto, tem muitas respostas desatualizadas. A partir de 2020, todos os principais navegadores aderiram ao padrão .

Resposta para 2020:

document.body.scrollHeight

Editar: o item acima não leva em consideração as margens da <body>tag. Se seu corpo tiver margens, use:

document.documentElement.scrollHeight
Marquizzo
fonte
hm - agora eu testá-lo e ele funciona - Eu não sei porque - assim ok :) - eu excluir meu comentário anterior
Kamil Kiełczewski
6
A partir de 2017, isso deve ser marcado como a resposta certa para mim.
7287 Joan
@Joan Isso é com o cartaz original para decidir :)
Marquizzo
Não funciona na presença de margens. document.documentElement.getBoundingClientRect()funciona melhor.
torvin
3
Há um erro com isso: digamos, por exemplo, que exista um <h1>elemento no início da <body>margem padrão, ele empurrará o <body>elemento para baixo sem uma maneira de detectá-lo. document.documentElement.scrollHeight(não document.body,scrollHeight) é a maneira mais precisa de fazer as coisas. Isso funciona tanto com as margens do corpo quanto com as coisas dentro do corpo, empurrando-o para baixo.
Ethan
29

Você pode até usar isso:

var B = document.body,
    H = document.documentElement,
    height

if (typeof document.height !== 'undefined') {
    height = document.height // For webkit browsers
} else {
    height = Math.max( B.scrollHeight, B.offsetHeight,H.clientHeight, H.scrollHeight, H.offsetHeight );
}

ou de uma maneira mais jQuery (já que você disse que o jQuery não mente) :)

Math.max($(document).height(), $(window).height())
Mimo
fonte
24

Cálculo da altura do documento completo:

Para ser mais genérico e encontrar a altura de qualquer documento, você pode encontrar o nó DOM mais alto na página atual com uma recursão simples:

;(function() {
    var pageHeight = 0;

    function findHighestNode(nodesList) {
        for (var i = nodesList.length - 1; i >= 0; i--) {
            if (nodesList[i].scrollHeight && nodesList[i].clientHeight) {
                var elHeight = Math.max(nodesList[i].scrollHeight, nodesList[i].clientHeight);
                pageHeight = Math.max(elHeight, pageHeight);
            }
            if (nodesList[i].childNodes.length) findHighestNode(nodesList[i].childNodes);
        }
    }

    findHighestNode(document.documentElement.childNodes);

    // The entire page height is found
    console.log('Page height is', pageHeight);
})();

Você pode testá-lo em seus sites de exemplo ( http://fandango.com/ ou http://paperbackswap.com/ ) colando esse script no DevTools Console.

NOTA: está trabalhando com Iframes.

Aproveitar!

Andrii Verbytskyi
fonte
2
Isso funcionou como um encanto! Nenhuma outra resposta aqui funciona para obter a altura total (incluindo a área de rolagem), todos retornam apenas a altura da área visível.
Martin Kristiansson
Realmente excepcional, nunca pensei nisso. Suponho que apenas um trabalhando em phantomjs.
MindlessRanger
6

O "método jQuery" para determinar o tamanho do documento - consulte tudo, obtenha o valor mais alto e espere o melhor - funciona na maioria dos casos, mas não em todos eles .

Se você realmente precisa de resultados à prova de balas para o tamanho do documento, sugiro que você use meu jQuery.documentSize plugin . Ao contrário dos outros métodos, ele testa e avalia o comportamento do navegador quando é carregado e, com base no resultado, consulta a propriedade correta a partir daí.

O impacto desse teste único no desempenho é mínimo , e o plug-in retorna os resultados corretos mesmo nos cenários mais estranhos - não porque eu digo isso, mas porque um conjunto de testes massivo e gerado automaticamente verifica o que realmente acontece.

Como o plug-in é escrito em Javascript baunilha, você também pode usá-lo sem o jQuery .

hashchange
fonte
5

Eu menti, jQuery retorna o valor correto para ambas as páginas $ (document) .height (); ... por que eu duvidei disso?

Nic
fonte
11
Navegadores diferentes, mano.
jahrichie
4

A resposta adequada para 2017 é:

document.documentElement.getBoundingClientRect().height

Ao contrário document.body.scrollHeightdeste método, é responsável pelas margens do corpo. Também fornece valor de altura fracionada, que pode ser útil em alguns casos

Torvin
fonte
11
Estes são os resultados que recebo quando tento seu método nesta página: i.imgur.com/0psVkIk.png Seu método retorna algo que se parece com a altura da janela, enquanto document.body.scrollHeightlista toda a altura rolável, que é a pergunta original.
Marquizzo
2
@ Marquizzo é porque esta página possui html { height: 100% }CSS. Portanto, a API retorna corretamente a altura calculada real . Tente remover esse estilo e também adicionar margens bodye você verá qual é o problema com o uso document.body.scrollHeight.
torvin
Há um erro com isso: digamos, por exemplo, que existe um <h1>elemento no início da <body>margem padrão, ele empurrará o <body>elemento para baixo sem uma maneira de detectá-lo. document.documentElement.scrollHeight(não document.body,scrollHeight) é a maneira mais precisa de fazer as coisas.
Ethan
@ Booligoosh não sei o que você quer dizer. documentElement.scrollHeightfornece um valor errado neste caso. documentElement.getBoundingClientRect().heightdá o correto. veja isso: jsfiddle.net/fLpqjsxd
torvin
11
@torvin O fato é que nem o resultado pretendido é retornado por getBoundingClientRect().height. Ele é desviado, enquanto 3 (três) outros métodos não são desviados. Incluindo o que você menciona como inferior a ele. E você insiste em fazer isso sugerindo remover 100% da altura html desta página e adicionando margens a ela. Qual é o objetivo? Apenas aceite que isso getBoundingClientRect().heighttambém não é à prova de balas.
Rob Waa
2

Para obter a largura de um navegador / dispositivo cruzado, use:

function getActualWidth() {
    var actualWidth = window.innerWidth ||
                      document.documentElement.clientWidth ||
                      document.body.clientWidth ||
                      document.body.offsetWidth;

    return actualWidth;
}
user937284
fonte
11
estamos falando de altura. não largura.
Yash
0

Para qualquer pessoa que tenha problemas para rolar uma página sob demanda, usando a detecção de recursos, criei esse hack para detectar qual recurso usar em um pergaminho animado.

O problema foi ao mesmo tempo document.body.scrollTope document.documentElementsempre retornadotrue em todos os navegadores.

No entanto, você só pode realmente rolar um documento com um ou outro. d.body.scrollToppara o Safari e document.documentElementpara todos os outros, de acordo com o w3schools (veja exemplos)

element.scrollTop funciona em todos os navegadores, não no nível do documento.

    // get and test orig scroll pos in Saf and similar 
    var ORG = d.body.scrollTop; 

    // increment by 1 pixel
    d.body.scrollTop += 1;

    // get new scroll pos in Saf and similar 
    var NEW = d.body.scrollTop;

    if(ORG == NEW){
        // no change, try scroll up instead
        ORG = d.body.scrollTop;
        d.body.scrollTop -= 1;
        NEW = d.body.scrollTop;

        if(ORG == NEW){
            // still no change, use document.documentElement
            cont = dd;
        } else {
            // we measured movement, use document.body
            cont = d.body;
        }
    } else {
        // we measured movement, use document.body
        cont = d.body;
    }
YK
fonte
-1

use código de golpe para calcular a altura + rolagem

var dif = document.documentElement.scrollHeight - document.documentElement.clientHeight;

var height = dif + document.documentElement.scrollHeight +"px";
Ali Bagheri
fonte
-1

Este código de navegador cruzado abaixo avalia todas as alturas possíveis dos elementos body e html e retorna o máximo encontrado:

            var body = document.body;
            var html = document.documentElement;
            var bodyH = Math.max(body.scrollHeight, body.offsetHeight, body.getBoundingClientRect().height, html.clientHeight, html.scrollHeight, html.offsetHeight); // The max height of the body

Um exemplo de trabalho:

function getHeight()
{
  var body = document.body;
  var html = document.documentElement; 
  var bodyH = Math.max(body.scrollHeight, body.offsetHeight, body.getBoundingClientRect().height, html.clientHeight, html.scrollHeight, html.offsetHeight);
  return bodyH;
}

document.getElementById('height').innerText = getHeight();
body,html
{
  height: 3000px;
}

#posbtm
{
  bottom: 0;
  position: fixed;
  background-color: Yellow;
}
<div id="posbtm">The max Height of this document is: <span id="height"></span> px</div>

example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />
example document body content example document body content example document body content example document body content <br />

Willy Wonka
fonte
Por favor, explique a motivação em caso de voto negativo, para que eu possa corrigir o ponto. Muito obrigado
willy wonka
-4

Não sei como determinar a altura agora, mas você pode usar isso para colocar algo na parte inferior:

<html>
<head>
<title>CSS bottom test</title>
<style>
.bottom {
  position: absolute;
  bottom: 1em;
  left: 1em;
}
</style>
</head>

<body>

<p>regular body stuff.</p>

<div class='bottom'>on the bottom</div>

</body>
</html>
jedihawk
fonte
11
Confie em mim, eu tenho recursos HTML e CSS esgotados neste. Não é possível explicar, mas você verá os problemas se tentar isso nesses sites.
1774 Nic
-4

Adicionar referências corretamente

No meu caso, eu estava usando uma página ASCX e a página aspx que contém o controle ascx não está usando as referências corretamente. Acabei de colar o seguinte código e funcionou:

<script src="../js/jquery-1.3.2-vsdoc.js" type="text/javascript"></script>
<script src="../js/jquery-1.3.2.js" type="text/javascript"></script>
<script src="../js/jquery-1.5.1.js" type="text/javascript"></script>
Tosh
fonte