¿Cómo obtener la altura de todo el documento con JavaScript?

333

Algunos documentos no puedo obtener la altura del documento (para colocar algo absolutamente en la parte inferior). Además, un relleno inferior parece no hacer nada en estas páginas, pero sí en las páginas donde volverá la altura. Caso (s) en punto:

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

En Fandango,
jQuery $(document).height();devuelve el valor correcto
document.heightdevuelve 0
document.body.scrollHeightdevuelve 0

En Paperback Swap:
jQuery's $(document).height();TypeError: $(document)es nulo
document.heightdevuelve un valor incorrecto
document.body.scrollHeightdevuelve un valor incorrecto

Nota: Tengo permisos de nivel de navegador, si hay algún truco allí.

Nic
fuente
55
$ (documento) es nulo porque ese sitio no tiene jQuery cargado ...
James
Hm, podría haber jurado que revisé algo más para confirmar que jQuery estaba registrado, pero no parece que lo haya hecho, ¡HA! Pensé que Firebug tenía jQuery empaquetado ... hm, supongo que lo comprobaré si es una solución.
Nic
44
firebug no tiene jQUery empaquetado
harsimranb
Consulte Encontrar el tamaño de la ventana del navegador . Tiene una gran tabla de comportamientos de diferentes navegadores.
Oriol

Respuestas:

671

Los tamaños de los documentos son una pesadilla de compatibilidad del navegador porque, aunque todos los navegadores exponen las propiedades clientHeight y scrollHeight, no todos están de acuerdo en cómo se calculan los valores.

Solía ​​haber una fórmula compleja de mejores prácticas sobre cómo se probó la altura / anchura correcta. Esto implicaba usar las propiedades document.documentElement si estaba disponible o recurrir a las propiedades del documento, etc.

La forma más sencilla de obtener la altura correcta es obtener todos los valores de altura encontrados en el documento o documentElement, y usar el más alto. Esto es básicamente lo que hace jQuery:

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

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

Una prueba rápida con Firebug + jQuery bookmarklet devuelve la altura correcta para ambas páginas citadas, y también lo hace el ejemplo de código.

Tenga en cuenta que probar la altura del documento antes de que el documento esté listo siempre dará como resultado un 0. Además, si carga más cosas o el usuario cambia el tamaño de la ventana, es posible que deba volver a realizar la prueba. Utilice onloadun evento listo para documentos si lo necesita en el momento de la carga; de lo contrario, solo pruebe cada vez que necesite el número.

Borgar
fuente
2
califique esta solución, porque funciona cuando está utilizando la biblioteca de prototipos, con jQuery no existe tal problema
se_pavel
10
Cuando se trabaja con iframes y jquery, debido a este método de cálculo, la altura del documento del iframe siempre será al menos la altura del iframe itselft. Es importante tener en cuenta cuándo desea reducir la altura del iframe para que coincida con el contenido. Primero debe restablecer la altura del iframe.
David Lay el
3
Tuve la necesidad de hacer crecer el iframe y reducirlo (aplicación de Facebook) y descubrí que document.body.offsetHeight era la mejor opción para mí, respaldado con precisión por la mayoría de los navegadores.
JeffG
1
Esto es muy bueno, aunque puede dar resultados incorrectos si el documento no está listo - es decir, cuando se utiliza en el código del servidor generada ...
stuartdotnet
1
Probar el documento antes de que esté listo no funcionará. Esto no tiene nada que ver con el código / documentos generados, sino con cómo se carga el documento. La prueba debe ejecutarse después de que el documento esté listo, y sugeriría ejecutarlo solo cuando el documento esté completamente cargado, ya que los elementos restantes pueden afectar la altura, también cambiando el tamaño del navegador.
Borgar
214

Esta es una pregunta muy antigua y, por lo tanto, tiene muchas respuestas obsoletas. A partir de 2020, todos los principales navegadores se han adherido al estándar .

Respuesta para 2020:

document.body.scrollHeight

Editar: lo anterior no tiene en cuenta los márgenes en la <body>etiqueta. Si su cuerpo tiene márgenes, use:

document.documentElement.scrollHeight
Marquizzo
fuente
hm - ahora lo pruebo y funciona - no sé por qué - tan bien :) -
borré
66
A partir de 2017, esto debería estar marcado como la respuesta correcta para mí.
Joan
@Joan Eso depende del póster original para decidir :)
Marquizzo
No funciona en presencia de márgenes. document.documentElement.getBoundingClientRect()Funciona mejor
torvin
3
Hay un error con esto: Digamos, por ejemplo, que hay un <h1>elemento al comienzo del <body>margen predeterminado, lo empujará <body>hacia abajo sin una forma de detectarlo. document.documentElement.scrollHeight(no document.body,scrollHeight) es la forma más precisa de hacer las cosas. Esto funciona con márgenes corporales y márgenes de cosas dentro del cuerpo empujándolo hacia abajo.
Ethan
29

Incluso puedes usar esto:

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 );
}

o de una manera más jQuery (ya que como dijiste jQuery no miente) :)

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

Cálculo completo de la altura del documento:

Para ser más genérico y encontrar la altura de cualquier documento , puede encontrar el nodo DOM más alto en la página actual con una simple recursión:

;(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);
})();

Puede probarlo en sus sitios de muestra ( http://fandango.com/ o http://paperbackswap.com/ ) pegando este script en una consola DevTools.

NOTA: está trabajando con Iframes.

¡Disfrutar!

Andrii Verbytskyi
fuente
2
¡Funcionó como por arte de magia! Ninguna otra respuesta aquí funciona para obtener la altura completa (incluido el área desplazable), todas devuelven solo la altura del área visible.
Martin Kristiansson
Realmente excepcional, nunca pensé en esto. Solo uno trabajando en phantomjs, supongo.
MindlessRanger
6

El "método jQuery" para determinar el tamaño del documento (consultar todo, tomar el valor más alto y esperar lo mejor) funciona en la mayoría de los casos, pero no en todos .

Si realmente necesita resultados a prueba de balas para el tamaño del documento, le sugiero que use mi complemento jQuery.documentSize . A diferencia de los otros métodos, en realidad prueba y evalúa el comportamiento del navegador cuando se carga y, en función del resultado, consulta la propiedad correcta a partir de ahí.

El impacto de esta prueba única en el rendimiento es mínimo , y el complemento devuelve los resultados correctos incluso en los escenarios más extraños, no porque yo lo diga, sino porque un conjunto de pruebas masivas y autogeneradas realmente verifica que lo hace.

Debido a que el complemento está escrito en Javascript vainilla, también puede usarlo sin jQuery .

hashchange
fuente
5

Mentí, jQuery devuelve el valor correcto para ambas páginas $ (document) .height (); ... ¿por qué alguna vez lo dudo?

Nic
fuente
1
Diferentes navegadores hermano.
jahrichie
4

La respuesta adecuada para 2017 es:

document.documentElement.getBoundingClientRect().height

A diferencia de document.body.scrollHeighteste método, se tienen en cuenta los márgenes corporales. También proporciona un valor de altura fraccional, que puede ser útil en algunos casos.

torvin
fuente
1
Estos son los resultados que obtengo cuando pruebo su método en esta página: i.imgur.com/0psVkIk.png Su método devuelve algo que se parece a la altura de la ventana, mientras document.body.scrollHeightenumera toda la altura desplazable, que es lo que hizo la pregunta original.
Marquizzo
2
@Marquizzo es porque esta página tiene html { height: 100% }en CSS. Por lo tanto, la API devuelve correctamente la altura real calculada. Intente eliminar este estilo y también agregar márgenes bodyy verá cuál es el problema con el uso document.body.scrollHeight.
torvin
Hay un error con esto: Digamos, por ejemplo, que hay un <h1>elemento al comienzo del <body>margen predeterminado, lo empujará <body>hacia abajo sin una forma de detectarlo. document.documentElement.scrollHeight(no document.body,scrollHeight) es la forma más precisa de hacer las cosas.
Ethan
@Booligoosh no estoy seguro de lo que quieres decir. documentElement.scrollHeightda un valor incorrecto en este caso. documentElement.getBoundingClientRect().heightda el correcto. mira
torvin
1
@torvin El hecho es que no se devuelve el resultado deseado getBoundingClientRect().height. Se desvía, mientras que otros 3 (tres) métodos no se desvían. Incluyendo el que mencionas como inferior a él. E insiste en hacerlo sugiriendo eliminar el 100% de la altura html de esta página y agregando márgenes. Cuál es el punto de ? Solo acepta que getBoundingClientRect().heighttampoco es a prueba de balas.
Rob Waa
2

Para obtener el ancho en una forma de navegador cruzado / dispositivo use:

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

    return actualWidth;
}
usuario937284
fuente
11
Estamos hablando de altura. no ancho
Yash
0

Para cualquiera que tenga problemas para desplazarse por una página a pedido, utilizando la detección de funciones, he creado este truco para detectar qué función usar en un desplazamiento animado.

El problema era ambos document.body.scrollTopy document.documentElementsiempre se devolvió trueen todos los navegadores.

Sin embargo, solo puede desplazar un documento con uno u otro. d.body.scrollToppara Safari y document.documentElementpara todos los demás según w3schools (ver ejemplos)

element.scrollTop funciona en todos los navegadores, no así para el nivel de 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
fuente
-1

use el código de soplo para calcular la altura + desplazamiento

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

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

El siguiente código de navegador cruzado evalúa todas las alturas posibles del cuerpo y los elementos html y devuelve el 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

Un ejemplo de trabajo:

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
fuente
Explique la motivación en caso de voto negativo para que pueda corregir el punto. Muchas gracias
willy wonka
-4

No sé cómo determinar la altura en este momento, pero puedes usar esto para poner algo en la 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
fuente
1
Confía en mí, he agotado los recursos HTML y CSS en este caso. No puedo explicarlo, pero verá los problemas si intenta esto en esos sitios.
Nic
-4

Agregar referencias correctamente

En mi caso, estaba usando una página ASCX y la página aspx que contiene el control ascx no está usando las referencias correctamente. Acabo de pegar el siguiente código y funcionó:

<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
fuente