¿Cómo puedo obtener los tamaños de barra de desplazamiento del navegador?


164

¿Cómo puedo determinar la altura de una barra de desplazamiento horizontal, o el ancho de una barra vertical, en JavaScript?


2
Aquí hay un fragmento del autor del complemento JQuery Dimension. github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/… tal vez tarde para dar esta solución, pero me parece una mejor, IMO.
Yanick Rochon el

Eche un vistazo a esta solución: davidwalsh.name/detect-scrollbar-width
GibboK

@GibboK: esa solución falla: offsetWidth == clientWidth, por lo que siempre es cero. Esto se prueba en Edge IE && Chrome.
beauXjames

1
@beauXjames raro, funciona para mí en FF
GibboK

Esta pregunta surge en la situación en la que la barra de desplazamiento está en la ubicación incorrecta (en algún lugar en el medio de la pantalla). En esta situación, probablemente no desee mostrar una barra de desplazamiento. En la mayoría de los casos, he encontrado que iScroll es la solución perfecta de diseño neutral para la situación: iscrolljs.com
JoostS

Respuestas:


139

Desde el blog de Alexandre Gomes no lo he probado. Avísame si te funciona.

function getScrollBarWidth () {
  var inner = document.createElement('p');
  inner.style.width = "100%";
  inner.style.height = "200px";

  var outer = document.createElement('div');
  outer.style.position = "absolute";
  outer.style.top = "0px";
  outer.style.left = "0px";
  outer.style.visibility = "hidden";
  outer.style.width = "200px";
  outer.style.height = "150px";
  outer.style.overflow = "hidden";
  outer.appendChild (inner);

  document.body.appendChild (outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild (outer);

  return (w1 - w2);
};

2
La idea es genial, definitivamente estoy haciendo una clase de MooTools basada en esto.
Ryan Florence

Sí, obtuve el mismo resultado de Google. :) Estoy tratando de mantenerte informado.
glmxndr

si cambia su tema a uno con barras de desplazamiento de diferentes tamaños, ¿cuál es la desviación calculada a real?
Matthew Vines

1
ver aquí para referencia cruzada: stackoverflow.com/questions/3417139/…
Yanick Rochon

66
Devuelve valores diferentes con zoom de página diferente. Win7, Opera, FF.
Kolyunya

79

Usando jQuery, puede acortar la respuesta de Matthew Vines a:

function getScrollBarWidth () {
    var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
        widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
    $outer.remove();
    return 100 - widthWithScroll;
};

2
¡Gracias, esta solución es muy limpia!
jherax

44
¿Esta solución realmente se sentiría más limpia si todo el código fuente de JQuery se copiara pegado antes? Porque eso es más o menos lo que está haciendo esta solución. Esta pregunta no solicitó una respuesta en JQuery, y es perfectamente posible y eficiente realizar esta tarea sin el uso de una biblioteca.
DaemonOfTheWest

55
Si ya está utilizando JQuery, el comentario de Daemon es irrelevante. Sí, agregar JQuery solo para hacer esto sería una tontería, pero para aquellos que ya usan JQuery en su proyecto, esta es una solución mucho más simple que la aceptada.
Tyler Dahle

25

Este es solo el script que he encontrado, que funciona en los navegadores webkit ... :)

$.scrollbarWidth = function() {
  var parent, child, width;

  if(width===undefined) {
    parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');
    child=parent.children();
    width=child.innerWidth()-child.height(99).innerWidth();
    parent.remove();
  }

 return width;
};

Versión minimizada:

$.scrollbarWidth=function(){var a,b,c;if(c===undefined){a=$('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');b=a.children();c=b.innerWidth()-b.height(99).innerWidth();a.remove()}return c};

Y debe llamarlo cuando el documento esté listo ... así que

$(function(){ console.log($.scrollbarWidth()); });

Probado el 28/03/2012 en Windows 7 en las últimas versiones de FF, Chrome, IE y Safari y funciona al 100%.

fuente: http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth


13
ancho SIEMPRE === indefinido en ese código. bien podría hacerlo si (verdadero) {...}
sstur

3
Corrección: widthserá siempre === sin definir la primera vez que la función se llama. En llamadas posteriores a la función widthya está configurada, esa verificación solo evita que los cálculos se ejecuten nuevamente innecesariamente.
MartinAnsty

17
@MartinAnsty Pero la variable [ancho] se declara dentro de la función, por lo tanto, se recrea cada vez que se llama a la función.
MadSkunk

44
@MartinAnsty, si nos fijamos en la fuente , se declara en el cierre exterior.
TheCloudlessSky

3
Solo para reforzar el punto hecho por @sstur y @TheCloudlessSky, el código anterior no es el mismo que el del complemento de Ben Alman, y no almacenará en caché el resultado width, sino que lo recalculará cada vez. Funciona, pero es terriblemente ineficiente. Hazle un favor al mundo y usa la versión correcta en el complemento de Alman.
hashchange

24

si está buscando una operación simple, simplemente mezcle dom js y jquery,

var swidth=(window.innerWidth-$(window).width());

devuelve el tamaño de la barra de desplazamiento de la página actual. (si es visible o si no, devolverá 0)


10
Esto fallará en caso de que la ventana no tenga barras de desplazamiento (monitor grande o página / aplicación pequeña)
Farid Nouri Neshat

1
esto es perfectamente lo que quería
azerafati

16
window.scrollBarWidth = function() {
  document.body.style.overflow = 'hidden'; 
  var width = document.body.clientWidth;
  document.body.style.overflow = 'scroll'; 
  width -= document.body.clientWidth; 
  if(!width) width = document.body.offsetWidth - document.body.clientWidth;
  document.body.style.overflow = ''; 
  return width; 
} 

Primero probé la respuesta aceptada pero descubrí que eso ya no funcionaba en Firefox en Windows 8. Cambié a esta variante que funciona muy bien.
Matijs

1
Código más corto, pero el navegador tiene que volver a dibujar toda la página, por lo que es muy lento.
Adrian Maire

11

Para mí, la forma más útil fue

(window.innerWidth - document.getElementsByTagName('html')[0].clientWidth)

con JavaScript vainilla.

ingrese la descripción de la imagen aquí


Gracias @ stephen-kendy. Un saludo.
Andrés Moreno

3
Justo lo que necesitaba. Una sugerencia: el segundo término puede ser reemplazado por document.documentElement.clientWidth. documentElementexpresa más clara y limpiamente la intención de obtener el <html>elemento.
Jan Miksovsky

9

Encontré una solución simple que funciona para los elementos dentro de la página, en lugar de la página en sí: $('#element')[0].offsetHeight - $('#element')[0].clientHeight

Esto devuelve la altura de la barra de desplazamiento del eje x.


¡¡Muy buena!! Me alegraste el día :) Funciona también con ".offsetWidth" y ".clientWidth" para las barras de desplazamiento del eje y.
Polosson

1
No parece del todo confiable, desafortunadamente, al menos para anchos. .clientWidth parece incluir la mitad del ancho de la barra de desplazamiento en FireFox y Chrome en Linux.
Michael Scheper

6

Del blog de David Walsh :

// Create the measurement node
var scrollDiv = document.createElement("div");
scrollDiv.className = "scrollbar-measure";
document.body.appendChild(scrollDiv);

// Get the scrollbar width
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
console.info(scrollbarWidth); // Mac:  15

// Delete the DIV 
document.body.removeChild(scrollDiv);
.scrollbar-measure {
	width: 100px;
	height: 100px;
	overflow: scroll;
	position: absolute;
	top: -9999px;
}

Me da 17 en mi sitio web, 14 aquí en Stackoverflow.


4

Si ya tiene un elemento con barras de desplazamiento, use:

function getScrollbarHeight(el) {
    return el.getBoundingClientRect().height - el.scrollHeight;
};

Si no hay horzintscrollbar presente, la función volverá a ejecutar 0


Esta es la mejor respuesta hasta ahora. KISS gobierna todo
MarcD

4

Puede determinar la windowbarra de desplazamiento de la documentsiguiente manera usando jquery + javascript:

var scrollbarWidth = ($(document).width() - window.innerWidth);
console.info("Window Scroll Bar Width=" + scrollbarWidth );

Tenga en cuenta que innerWidth es para IE9 +. De lo contrario, es una gran solución.
Pål Thingbø

3

La forma en Antiscroll.jsque lo hace en su código es:

function scrollbarSize () {
  var div = $(
      '<div class="antiscroll-inner" style="width:50px;height:50px;overflow-y:scroll;'
    + 'position:absolute;top:-200px;left:-200px;"><div style="height:100px;width:100%"/>'
    + '</div>'
  );

  $('body').append(div);
  var w1 = $(div).innerWidth();
  var w2 = $('div', div).innerWidth();
  $(div).remove();

  return w1 - w2;
};

El código es de aquí: https://github.com/LearnBoost/antiscroll/blob/master/antiscroll.js#L447


3
detectScrollbarWidthHeight: function() {
    var div = document.createElement("div");
    div.style.overflow = "scroll";
    div.style.visibility = "hidden";
    div.style.position = 'absolute';
    div.style.width = '100px';
    div.style.height = '100px';
    document.body.appendChild(div);

    return {
        width: div.offsetWidth - div.clientWidth,
        height: div.offsetHeight - div.clientHeight
    };
},

Probado en Chrome, FF, IE8, IE11.


2

Esto debería hacer el truco, ¿no?

function getScrollbarWidth() {
  return (window.innerWidth - document.documentElement.clientWidth);
}

2

Cree un espacio vacío divy asegúrese de que esté presente en todas las páginas (es decir, colocándolo en elheader plantilla).

Dale este estilo:

#scrollbar-helper {
    // Hide it beyond the borders of the browser
    position: absolute;
    top: -100%;

    // Make sure the scrollbar is always visible
    overflow: scroll;
}

Luego simplemente verifique el tamaño de #scrollbar-helpercon Javascript:

var scrollbarWidth = document.getElementById('scrollbar-helper').offsetWidth;
var scrollbarHeight = document.getElementById('scrollbar-helper').offsetHeight;

No es necesario calcular nada, ya que esto divsiempre tendrá el widthy heightdel scrollbar.

El único inconveniente es que habrá divplantillas vacías en sus plantillas. Pero, por otro lado, sus archivos Javascript estarán más limpios, ya que esto solo requiere 1 o 2 líneas de código.


1
function getWindowScrollBarHeight() {
    let bodyStyle = window.getComputedStyle(document.body);
    let fullHeight = document.body.scrollHeight;
    let contentsHeight = document.body.getBoundingClientRect().height;
    let marginTop = parseInt(bodyStyle.getPropertyValue('margin-top'), 10);
    let marginBottom = parseInt(bodyStyle.getPropertyValue('margin-bottom'), 10);
    return fullHeight - contentHeight - marginTop - marginBottom;
  }

1
function getScrollBarWidth() {
    return window.innerWidth - document.documentElement.clientWidth;
}

La mayoría del navegador usa 15px para el ancho de la barra de desplazamiento


0

Con jquery (solo probado en firefox):

function getScrollBarHeight() {
    var jTest = $('<div style="display:none;width:50px;overflow: scroll"><div style="width:100px;"><br /><br /></div></div>');
    $('body').append(jTest);
    var h = jTest.innerHeight();
    jTest.css({
        overflow: 'auto',
        width: '200px'
    });
    var h2 = jTest.innerHeight();
    return h - h2;
}

function getScrollBarWidth() {
    var jTest = $('<div style="display:none;height:50px;overflow: scroll"><div style="height:100px;"></div></div>');
    $('body').append(jTest);
    var w = jTest.innerWidth();
    jTest.css({
        overflow: 'auto',
        height: '200px'
    });
    var w2 = jTest.innerWidth();
    return w - w2;
}

Pero en realidad me gusta más la respuesta de @ Steve.


0

Esta es una gran respuesta: https://stackoverflow.com/a/986977/5914609

Sin embargo, en mi caso no funcionó. Y pasé horas buscando la solución.
Finalmente, volví al código anterior y agregué! Importante a cada estilo. Y funcionó.
No puedo agregar comentarios debajo de la respuesta original. Así que aquí está la solución:

function getScrollBarWidth () {
  var inner = document.createElement('p');
  inner.style.width = "100% !important";
  inner.style.height = "200px !important";

  var outer = document.createElement('div');
  outer.style.position = "absolute !important";
  outer.style.top = "0px !important";
  outer.style.left = "0px !important";
  outer.style.visibility = "hidden !important";
  outer.style.width = "200px !important";
  outer.style.height = "150px !important";
  outer.style.overflow = "hidden !important";
  outer.appendChild (inner);

  document.body.appendChild (outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll !important';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild (outer);

  return (w1 - w2);
};

0

Esta decisión de pirateo le dará la oportunidad de encontrar el ancho de desplazamiento del navegador (JavaScript estándar ). Con este ejemplo, puede obtener el ancho de desplazamiento en cualquier elemento, incluidos los elementos que no deberían tener desplazamiento de acuerdo con su concepción de diseño actual:

getComputedScrollYWidth     (el)  {

  let displayCSSValue  ; // CSS value
  let overflowYCSSValue; // CSS value

  // SAVE current original STYLES values
  {
    displayCSSValue   = el.style.display;
    overflowYCSSValue = el.style.overflowY;
  }

  // SET TEMPORALLY styles values
  {
    el.style.display   = 'block';
    el.style.overflowY = 'scroll';
  }

  // SAVE SCROLL WIDTH of the current browser.
  const scrollWidth = el.offsetWidth - el.clientWidth;

  // REPLACE temporally STYLES values by original
  {
    el.style.display   = displayCSSValue;
    el.style.overflowY = overflowYCSSValue;
  }

  return scrollWidth;
}

0

Aquí está la solución más concisa y fácil de leer basada en la diferencia de ancho de desplazamiento:

function getScrollbarWidth(): number {

  // Creating invisible container
  const outer = document.createElement('div');
  outer.style.visibility = 'hidden';
  outer.style.overflow = 'scroll'; // forcing scrollbar to appear
  outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps
  document.body.appendChild(outer);

  // Creating inner element and placing it in the container
  const inner = document.createElement('div');
  outer.appendChild(inner);

  // Calculating difference between container's full width and the child width
  const scrollbarWidth = (outer.offsetWidth - inner.offsetWidth);

  // Removing temporary elements from the DOM
  outer.parentNode.removeChild(outer);

  return scrollbarWidth;

}

Ver el JSFiddle .


0

Ya codificado en mi biblioteca, así que aquí está:

var vScrollWidth = window.screen.width - window.document.documentElement.clientWidth;

Debo mencionar que jQuery $(window).width()también se puede usar en lugar de window.document.documentElement.clientWidth.

No funciona si abre las herramientas de desarrollador en Firefox a la derecha, pero lo supera si la ventana de desarrollo se abre en la parte inferior.

window.screenes compatible quirksmode.org !

¡Que te diviertas!


0

Parece funcionar, pero ¿tal vez hay una solución más simple que funcione en todos los navegadores?

// Create the measurement node
var scrollDiv = document.createElement("div");
scrollDiv.className = "scrollbar-measure";
document.body.appendChild(scrollDiv);

// Get the scrollbar width
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
console.info(scrollbarWidth); // Mac:  15

// Delete the DIV 
document.body.removeChild(scrollDiv);
.scrollbar-measure {
	width: 100px;
	height: 100px;
	overflow: scroll;
	position: absolute;
	top: -9999px;
}

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.