¿Detectar si una página tiene una barra de desplazamiento vertical?

121

Solo quiero que JQ / JS simple verifique si la página / ventana actual (no un elemento en particular) tiene una barra de desplazamiento vertical.

Googlear me da cosas que parecen demasiado complejas solo por esta característica básica.

¿Cómo se puede hacer esto?

Leñoso
fuente

Respuestas:

97
$(document).ready(function() {
    // Check if body height is higher than window height :)
    if ($("body").height() > $(window).height()) {
        alert("Vertical Scrollbar! D:");
    }

    // Check if body width is higher than window width :)
    if ($("body").width() > $(window).width()) {
        alert("Horizontal Scrollbar! D:<");
    }
});
Thiago Belem
fuente
14
+1 pero en aras de la exactitud, esto solo comprueba si el contenido se expande más allá de la ventana gráfica. Si la overflowpropiedad de bodyse establece en hiddenalgún lugar a lo largo de la línea, no funcionará. Sin embargo, la configuración oculta en un cuerpo es extremadamente rara.
Pekka
44
Esto no funciona si la altura del cuerpo coincide con la altura de la ventana, que es el caso si la altura del documento coincide exactamente con la ventana gráfica y luego se agrega una barra de desplazamiento horizontal . Forzará el vert. barra de desplazamiento pero doc / body / window height son iguales; NO alertará a la "barra de desplazamiento vertical" aunque haya una.
Deja de calumniar a Monica Cellio el
2
Solo pensé en mencionar que tenía que usar en $(document)lugar de $("body"), esto funcionó para mí cuando el cuerpo no lo hizo (tengo un contenedor positivamente absoluto con una relación de aspecto en ancho / alto)
am_
1
Tengo una página de informe en el navegador Chrome donde inicialmente muestra una barra de desplazamiento y desaparece en cuestión de milisegundos, lo que parece un comportamiento del navegador ya que no lo programé. Así que esta función siempre es verdadera en mi caso ...
Dush
@TiuTalk for me $ ("body"). Height () & $ (window) .height () da el mismo valor, en su lugar uso $ (document) .height ()> $ (window) .height () funciona para yo.
SarangK
77

prueba esto:

var hasVScroll = document.body.scrollHeight > document.body.clientHeight;

Sin embargo, esto solo le indicará si el scrollHeight vertical es mayor que la altura del contenido visible. La hasVScrollvariable contendrá verdadero o falso.

Si necesita hacer una verificación más exhaustiva, agregue lo siguiente al código anterior:

// Get the computed style of the body element
var cStyle = document.body.currentStyle||window.getComputedStyle(document.body, "");

// Check the overflow and overflowY properties for "auto" and "visible" values
hasVScroll = cStyle.overflow == "visible" 
             || cStyle.overflowY == "visible"
             || (hasVScroll && cStyle.overflow == "auto")
             || (hasVScroll && cStyle.overflowY == "auto");
Andy E
fuente
1
+1 Nice! Y con el estilo computacional necesario (que fue el punto en el que decidí no involucrarme con esta pregunta;)
Pekka
lol, sí, estaba debatiendo si hacer un esfuerzo adicional para escribirlo porque en muchos casos no es necesario.
Andy E
1
Esto da como resultado que hasVScroll sea verdadero cuando el desbordamiento es 'visible' independientemente de si scrollHeight es mayor que clientHeight. Quizás quisiste decir cStyle.overflow === 'scroll'?
BT
55
El código anterior no funciona. Navegador: Chrome 56. Url: news.greylock.com/…
Sebastien Lorber
1
@BT cStyle.overflow == "visible" puede mostrar barras de desplazamiento cuando el elemento es el document.body. Pero debería ser (hasVScroll && cStyle.overflow == "visible" && element.nodeName == "BODY"). Además, debe verificarlo cStyle.overflow === 'scroll'como usted señala.
mseifert
44

Intenté la respuesta anterior y parece que no funciona $ ("body"). Height () no necesariamente representa la altura html completa.

He corregido la solución de la siguiente manera:

// Check if body height is higher than window height :) 
if ($(document).height() > $(window).height()) { 
    alert("Vertical Scrollbar! D:"); 
} 

// Check if body width is higher than window width :) 
if ($(document).width() > $(window).width()) { 
    alert("Horizontal Scrollbar! D:<"); 
} 
Bharat
fuente
18

Traigamos esta pregunta de la muerte;) Hay una razón por la cual Google no le da una solución simple. Los casos especiales y las peculiaridades del navegador afectan el cálculo, y no es tan trivial como parece ser.

Desafortunadamente, hay problemas con las soluciones descritas aquí hasta ahora. No pretendo menospreciarlos en absoluto: son excelentes puntos de partida y tocan todas las propiedades clave necesarias para un enfoque más sólido. Pero no recomendaría copiar y pegar el código de ninguna de las otras respuestas porque

  • no capturan el efecto del contenido posicionado de una manera que sea confiable entre navegadores. Las respuestas que se basan en el tamaño del cuerpo pasan por alto esto completamente (el cuerpo no es el padre compensador de dicho contenido a menos que esté posicionado). Y esas respuestas se comprueban $( document ).width()y .height()son víctimas de la detección de errores de jQuery del tamaño del documento .
  • Confiar en window.innerWidth, si el navegador lo admite, hace que su código no detecte las barras de desplazamiento en los navegadores móviles, donde el ancho de la barra de desplazamiento es generalmente 0. Simplemente se muestran temporalmente como una superposición y no ocupan espacio en el documento . Zoom en dispositivos móviles también se convierte en un problema de esa manera (larga historia).
  • La detección puede ser arrojado fuera cuando las personas establecen explícitamente el desbordamiento de ambos htmly el bodyelemento a los valores no predeterminados (lo que sucede a continuación es un poco involucrados - ver esta descripción ).
  • En la mayoría de las respuestas, el relleno del cuerpo, los bordes o los márgenes no se detectan y distorsionan los resultados.

He pasado más tiempo del que hubiera imaginado para encontrar una solución que "simplemente funcione" (tos). El algoritmo que se me ocurrió ahora es parte de un complemento, jQuery.isInView , que expone un .hasScrollbarmétodo . Echa un vistazo a la fuente si lo deseas.

En un escenario en el que tienes el control total de la página y no tienes que lidiar con CSS desconocido, usar un complemento puede ser excesivo; después de todo, sabes qué casos límite se aplican y cuáles no. Sin embargo, si necesita resultados confiables en un entorno desconocido, entonces no creo que las soluciones descritas aquí sean suficientes. Es mejor usar un complemento bien probado: el mío o el de cualquier otra persona.

hashchange
fuente
Gracias. ¡Bastante complicado! Si no desea / necesita ser compatible con versiones anteriores, ¿existe quizás una solución más fácil para los navegadores html5? Quiero decir, ¿tal vez los codificadores del navegador / w3c han sido lo suficientemente amables como para decirnos si hay barras de desplazamiento o no en un elemento? ;-)
Leo
1
@Leo No que yo sepa. Bueno, hay un window.scrollbarsobjeto que tiene una sola propiedad visible,. Suena prometedor pero no lo es. No es compatible con IE, incluido IE11. Y solo te dice que hay una barra de desplazamiento, pero no cuál. Vea la página de prueba aquí .
hashchange
Gracias @hashchange. Suena increíblemente estúpido que solo diga si hay alguna barra de desplazamiento, así que supongo que todavía es una especie de prueba. Aunque un poco prometedor. ;-)
Leo
1
@BT Ok, genial. Ahora déjame guiarte a la entrada de la madriguera del conejo;) Aquí hay una demostración donde el contenido no es suficiente para llenar la ventana. Su detección funciona en FF pero falla en Chrome. Y aquí hay otra demostración donde un elemento posicionado se coloca muy abajo en la página. Su detección funciona en Chrome pero falla en FF.
hashchange del
1
@BT Y supongo que podemos entrar en un montón de modos de falla extraños cuando comenzamos a jugar con configuraciones de desbordamiento porque su comportamiento es un poco extraño , pero me detuve allí.
hashchange
15

Este sí funciona para mí:

function hasVerticalScroll(node){
    if(node == undefined){
        if(window.innerHeight){
            return document.body.offsetHeight> window.innerHeight;
        }
        else {
            return  document.documentElement.scrollHeight > 
                document.documentElement.offsetHeight ||
                document.body.scrollHeight>document.body.offsetHeight;
        }
    }
    else {
        return node.scrollHeight> node.offsetHeight;
    }
}

Para el cuerpo, solo use hasVerticalScroll().

Kees C. Bakker
fuente
Esta es la única respuesta en este hilo que funciona en mi Chrome
Nertan Lucian
clientHeightEs preferible por offsetHeightaquí. De lo contrario, puede tener un borde grueso y volver no hay barra de desplazamiento cuando la hay.
theicfire
12
var hasScrollbar = window.innerWidth > document.documentElement.clientWidth;
Roman Zaykovsky
fuente
Esto hizo el trabajo, gracias.
Vignesh Chinnaiyan
3

Curiosamente, ninguna de estas soluciones le dice si una página tiene una barra de desplazamiento vertical.

window.innerWidth - document.body.clientWidthle dará el ancho de la barra de desplazamiento. Esto debería funcionar en cualquier cosa IE9 + (no probado en los navegadores menores). (O para responder estrictamente a la pregunta,!!(window.innerWidth - document.body.clientWidth)

¿Por qué? Supongamos que tiene una página donde el contenido es más alto que la altura de la ventana y el usuario puede desplazarse hacia arriba / abajo. Si está utilizando Chrome en una Mac sin un mouse conectado, el usuario no verá una barra de desplazamiento. Conecte un mouse y aparecerá una barra de desplazamiento. (Tenga en cuenta que este comportamiento puede anularse, pero ese es el AFAIK predeterminado).

David Gilbertson
fuente
La explicación del comportamiento de Chrome-Mouse me ayudó a descubrir lo que pensé que era un comportamiento inconsistente. ¡Gracias!
theisof
2

Encontré solución de vainilla

var hasScrollbar = function() {
  // The Modern solution
  if (typeof window.innerWidth === 'number')
    return window.innerWidth > document.documentElement.clientWidth

  // rootElem for quirksmode
  var rootElem = document.documentElement || document.body

  // Check overflow style property on body for fauxscrollbars
  var overflowStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowStyle = rootElem.currentStyle.overflow

  overflowStyle = overflowStyle || window.getComputedStyle(rootElem, '').overflow

    // Also need to check the Y axis overflow
  var overflowYStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowYStyle = rootElem.currentStyle.overflowY

  overflowYStyle = overflowYStyle || window.getComputedStyle(rootElem, '').overflowY

  var contentOverflows = rootElem.scrollHeight > rootElem.clientHeight
  var overflowShown    = /^(visible|auto)$/.test(overflowStyle) || /^(visible|auto)$/.test(overflowYStyle)
  var alwaysShowScroll = overflowStyle === 'scroll' || overflowYStyle === 'scroll'

  return (contentOverflows && overflowShown) || (alwaysShowScroll)
}

Sergii Shvager
fuente
1
No funciona en IE 11. window.innerWidth y document.documentElement.clientWidth son siempre iguales.
NLV
Arreglado. Esta misma función también funciona para IE 11. El problema era este - stackoverflow.com/questions/17045132/…
NLV
Probé esto en Chrome 65 y funciona. Pero cuando lo adapto para barras de desplazamiento horizontales, el resultado es extraño: si se muestran tanto la barra de desplazamiento horizontal como la vertical, window.innerWidth > document.documentElement.clientWidthes cierto, pero window.innerHeight > document.documentElement.clientHeightno lo es. Parece como si fuera al revés en este caso. No soy un desarrollador de JS, solo lo necesito para las pruebas de Selenium. Estoy agradecido por las pistas.
kriegaex
2
    <script>
    var scrollHeight = document.body.scrollHeight;
    var clientHeight = document.documentElement.clientHeight;
    var hasVerticalScrollbar = scrollHeight > clientHeight;

    alert(scrollHeight + " and " + clientHeight); //for checking / debugging.
    alert("hasVerticalScrollbar is " + hasVerticalScrollbar + "."); //for checking / debugging.
    </script>

Este te dirá si tienes una barra de desplazamiento o no. He incluido información que puede ayudar con la depuración, que se mostrará como una alerta de JavaScript.

Ponga esto en una etiqueta de script, después de la etiqueta de cierre del cuerpo.

Don D.
fuente
1

Escribí una versión actualizada de la respuesta de Kees C. Bakker:

const hasVerticalScroll = (node) => {
  if (!node) {
    if (window.innerHeight) {
      return document.body.offsetHeight > window.innerHeight
    }
    return (document.documentElement.scrollHeight > document.documentElement.offsetHeight)
      || (document.body.scrollHeight > document.body.offsetHeight)
  }
  return node.scrollHeight > node.offsetHeight
}

if (hasVerticalScroll(document.querySelector('body'))) {
  this.props.handleDisableDownScrollerButton()
}

La función devuelve verdadero o falso dependiendo de si la página tiene una barra de desplazamiento vertical o no.

Por ejemplo:

const hasVScroll = hasVerticalScroll(document.querySelector('body'))

if (hasVScroll) {
  console.log('HAS SCROLL', hasVScroll)
}
agm1984
fuente
1

yo suelo

public windowHasScroll()
{
    return document.body.clientHeight > document.documentElement.clientHeight;
}
amoss
fuente
1

Simplemente compare el ancho del elemento raíz de los documentos (es decir, el elemento html) con la parte interna de la ventana:

if ((window.innerWidth - document.documentElement.clientWidth) >0) console.log('V-scrollbar active')

Si también necesita saber el ancho de la barra de desplazamiento:

vScrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
Babak
fuente
0

Otras soluciones no funcionaron en uno de mis proyectos y terminé verificando la propiedad CSS de desbordamiento

function haveScrollbar() {
    var style = window.getComputedStyle(document.body);
    return style["overflow-y"] != "hidden";
}

pero solo funcionará si la barra de desplazamiento parece desaparecer cambiando el accesorio, no funcionará si el contenido es igual o menor que la ventana.

jcubic
fuente