Como posso obter os tamanhos da barra de rolagem do navegador?

164

Como posso determinar a altura de uma barra de rolagem horizontal ou a largura de uma vertical, em JavaScript?

glmxndr
fonte
2
Aqui está um trecho do autor do plugin JQuery Dimension. github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/… talvez esteja atrasado para fornecer esta solução, mas me parece melhor, IMO.
Yanick Rochon
Dê uma olhada nesta solução: davidwalsh.name/detect-scrollbar-width
GibboK
@ GibibK - essa solução falha - o offsetWidth == clientWidth, portanto é sempre zero. Isso é testado no Edge IE && Chrome.
beauXjames
1
@beauXjames estranho ele funciona para mim no FF
GibboK
Essa pergunta surge na situação em que a barra de rolagem está no local errado (em algum lugar no meio da tela). Nesta situação, você provavelmente não deseja mostrar uma barra de rolagem. Na maioria dos casos eu encontrei iScroll ser a solução perfeita de design neutro para a situação: iscrolljs.com
JoostS

Respostas:

139

Do blog Alexandre Gomes eu não tentei. Deixe-me saber se funciona para você.

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
fonte
2
A ideia é genial, eu definitivamente estou criando uma classe MooTools com base nisso.
22919 Ryan Florence
Sim, eu tenho o mesmo resultado do google. :) Estou tentando mantê-lo informado.
glmxndr
se você alterar seu tema para um com barras de rolagem de tamanhos diferentes, qual é o desvio calculado para real?
Matthew Vines
1
veja aqui para referência cruzada: stackoverflow.com/questions/3417139/…
Yanick Rochon
6
Retorna valores diferentes com zoom de página diferente. Win7, Opera, FF.
Kolyunya
79

Usando o jQuery, você pode reduzir a resposta de Matthew Vines para:

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
fonte
2
Obrigado, esta solução é muito limpa !!
jherax
4
Essa solução seria realmente mais limpa se todo o código-fonte do JQuery fosse copiado e colado antes dele? Porque isso é basicamente o que esta solução está fazendo. Esta pergunta não solicitou uma resposta no JQuery e é perfeitamente possível e eficiente executar essa tarefa sem o uso de uma biblioteca.
DaemonOfTheWest 19/08
5
Se você já estiver usando o JQuery, o comentário do Daemon é irrelevante. Sim, adicionar JQuery apenas para fazer isso seria um absurdo, mas para aqueles que já usam o JQuery em seu projeto, essa é uma solução muito mais simples do que a aceita.
precisa
25

Este é apenas o script que encontrei, que está funcionando nos navegadores de kit da web ... :)

$.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;
};

Versão 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};

E você tem que chamá-lo quando o documento estiver pronto ... então

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

Testado em 2012-03-28 no Windows 7 no mais recente FF, Chrome, IE e Safari e 100% funcionando.

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

Jan Šafránek
fonte
13
width SEMPRE === indefinido nesse código. poderia muito bem fazer se (true) {...}
SSTUR
3
Correção: widthvai sempre === indefinido a primeira vez que a função é chamada. Nas chamadas subsequentes para a função widthjá estão definidas, essa verificação apenas impede que os cálculos sejam executados novamente desnecessariamente.
MartinAnsty
17
@MartinAnsty Mas a variável [width] é declarada dentro da função, portanto é recriada toda vez que você chama a função.
precisa saber é o seguinte
4
@ MartinAnsty, se você olhar para a fonte , ela será declarada no fechamento externo.
#ClasslessSky #
3
Apenas para reforçar o argumento de @sstur e @TheCloudlessSky, o código acima não é o mesmo do plug-in de Ben Alman e não armazenará em cache o resultado width, mas recalculá-lo sempre. Funciona, mas é terrivelmente ineficiente. Por favor, faça um favor ao mundo e use a versão correta no plugin de Alman.
hashchange
24

se você estiver procurando por uma operação simples, basta misturar dom js e jquery simples,

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

retorna o tamanho da barra de rolagem da página atual. (se estiver visível ou retornará 0)

Beep.exe
fonte
10
Isto irá falhar no caso de que a janela não tem barras de rolagem (monitor grande ou pequena página / app)
Farid Nouri Neshat
1
isso é perfeitamente o que eu queria
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
fonte
Primeiro tentei a resposta aceita, mas achei que isso não funcionava mais no Firefox no Windows 8. Alternamos para essa variante que faz o trabalho perfeitamente.
Matijs 13/03/14
1
Código mais curto, mas o navegador precisa redesenhar a página inteira, por isso é muito lento.
Adrian Maire
11

Para mim, a maneira mais útil foi

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

com JavaScript baunilha.

insira a descrição da imagem aqui

Andrés Moreno
fonte
Obrigado @ stephen-kendy. Uma saudação.
Andrés Moreno
3
Apenas o que eu precisava. Uma sugestão: O segundo termo pode ser substituído por document.documentElement.clientWidth. documentElementmais clara e limpa expressa a intenção de obter o <html>elemento.
Jan Miksovsky,
9

Encontrei uma solução simples que funciona para elementos dentro da página, em vez da própria página: $('#element')[0].offsetHeight - $('#element')[0].clientHeight

Isso retorna a altura da barra de rolagem do eixo x.

Memet Olsen
fonte
Muito bom!! Você fez o meu dia :) Também está funcionando com ".offsetWidth" e ".clientWidth" para barras de rolagem no eixo y.
Polosson 26/09/14
1
Infelizmente, não parece totalmente confiável, pelo menos para larguras. .clientWidth parece incluir metade da largura da barra de rolagem no FireFox e no Chrome no Linux.
Michael Scheper
6

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

Dá-me 17 no meu site, 14 aqui no Stackoverflow.

mpen
fonte
4

Se você já possui um elemento com barras de rolagem, use:

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

Se não houver horzintscrollbar presente, a função retornará 0

mons droid
fonte
Esta é a melhor resposta ainda. O KISS governa tudo
MarcD 16/05
4

Você pode determinar a windowbarra de rolagem documentcomo abaixo, usando jquery + javascript:

var scrollbarWidth = ($(document).width() - window.innerWidth);
console.info("Window Scroll Bar Width=" + scrollbarWidth );
Bhuwan Prasad Upadhyay
fonte
Observe que innerWidth é para o IE9 +. Caso contrário, ótima solução.
Pål Thingbø
3

A maneira como Antiscroll.jsfaz isso em seu código é:

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

O código é daqui: https://github.com/LearnBoost/antiscroll/blob/master/antiscroll.js#L447

Hengjie
fonte
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
    };
},

Testado no Chrome, FF, IE8, IE11.

Ben
fonte
2

Isso deve funcionar, não?

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

Crie um vazio dive verifique se ele está presente em todas as páginas (ou seja, colocando-o no headermodelo).

Dê a ele esse estilo:

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

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

Em seguida, basta verificar o tamanho do #scrollbar-helperJavascript:

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

Não há necessidade de calcular nada, pois isso divsempre terá o widthe heightdo scrollbar.

A única desvantagem é que haverá um espaço vazio divnos seus modelos. Mas, por outro lado, seus arquivos Javascript serão mais limpos, pois isso requer apenas 1 ou 2 linhas de código.

Aquele cara
fonte
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
fonte
1
function getScrollBarWidth() {
    return window.innerWidth - document.documentElement.clientWidth;
}

A maioria do navegador usa 15px para a largura da barra de rolagem

Shadow Grimes
fonte
0

Com jquery (testado apenas no 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;
}

Mas na verdade eu gosto mais da resposta de Steve.

ling
fonte
0

Esta é uma ótima resposta: https://stackoverflow.com/a/986977/5914609

No entanto, no meu caso, não funcionou. E passei horas procurando a solução.
Finalmente voltei ao código acima e adicionei! Important para cada estilo. E funcionou.
Não consigo adicionar comentários abaixo da resposta original. Então, aqui está a correção:

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
fonte
0

Essa decisão de invasão de vida lhe dará a oportunidade de encontrar a largura de rolagem do navegador ( largura do navegador ). Usando este exemplo, você pode obter a largura scrollY em qualquer elemento, incluindo os elementos que não precisam ter rolagem de acordo com sua concepção de design atual:

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
fonte
0

Aqui está a solução mais concisa e fácil de ler, com base na diferença de largura de deslocamento:

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;

}

Veja o JSFiddle .

Slava Fomin II
fonte
0

Já codificado na minha biblioteca, então aqui está:

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

Devo mencionar que o jQuery $(window).width()também pode ser usado em vez de window.document.documentElement.clientWidth.

Não funciona se você abrir ferramentas de desenvolvedor no firefox à direita, mas será superado se a janela devs for aberta na parte inferior!

window.screen é suportado quirksmode.org !

Diverta-se!

centuriano
fonte
0

Parece funcionar, mas talvez haja uma solução mais simples que funcione em todos os 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
fonte