¿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?

glmxndr
fuente
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);
};
Matthew Vines
fuente
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;
};
Joshua Bambrick
fuente
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

Jan Šafránek
fuente
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)

Beep.exe
fuente
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; 
} 
Josh Stodola
fuente
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í

Andrés Moreno
fuente
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.

Memet Olsen
fuente
¡¡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.

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

Mons Droid
fuente
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 );
Bhuwan Prasad Upadhyay
fuente
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

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

Ben
fuente
2

Esto debería hacer el truco, ¿no?

function getScrollbarWidth() {
  return (window.innerWidth - document.documentElement.clientWidth);
}
Alejandro
fuente
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.

Ese tipo
fuente
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;
  }
allenhwkim
fuente
1
function getScrollBarWidth() {
    return window.innerWidth - document.documentElement.clientWidth;
}

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

Grimes sombríos
fuente
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.

abadejo
fuente
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);
};
Max Vetriakov
fuente
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;
}
Evgeniy Miroshnichenko
fuente
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 .

Slava Fomin II
fuente
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!

centurias
fuente
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;
}

Goga
fuente