如何获得浏览器的滚动条大小?


164

如何在JavaScript中确定水平滚动条的高度或垂直滚动​​条的宽度?


2
这是JQuery Dimension插件作者的摘录。github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/…也许来不及提供这种解决方案,但对我来说,IMO似乎是一个更好的解决方案。
Yanick Rochon


@GibboK-该解决方案失败-offsetWidth == clientWidth,因此始终为零。已在Edge IE && Chrome中测试过。
beauXjames

1
@beauXjames很奇怪,它在FF上对我
有用

在滚动条位于错误位置(屏幕中间的某个位置)的情况下会出现此问题。在这种情况下,您可能不想显示滚动条。在大多数情况下,我发现iScroll是针对这种情况的完美设计中立解决方案:iscrolljs.com
JoostS,2016年

Answers:


139

Alexandre Gomes博客开始, 我还没有尝试过。请让我知道这对你有没有用。

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
这个想法很天才,我肯定是在此基础上制作MooTools类。
Ryan Florence

是的,我得到了相同的Google结果。:)我正在努力让您知情。
glmxndr 2009年

如果将主题更改为具有不同大小滚动条的主题,则计算出的实际偏差是多少?
马修·维尼斯

1
在这里看到的交叉引用:stackoverflow.com/questions/3417139/...
Yanick罗森

6
使用不同的页面缩放返回不同的值。Win7,Opera,FF。
Kolyunya

79

使用jQuery,您可以将Matthew Vines的答案缩短为:

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
谢谢,这个解决方案很干净!!
jherax 2014年

4
如果将JQuery的整个源代码复制到该解决方案之前,此解决方案真的会更干净吗?因为这几乎就是该解决方案正在做的事情。这个问题并没有在JQuery中要求答案,并且完全可能并且高效地执行此任务而无需使用库。
2013年

5
如果您已经在使用JQuery,则Daemon的注释是无关紧要的。是的,仅仅为了做到这一点而添加JQuery就是胡说八道,但是对于那些已经在其项目中使用JQuery的人来说,这是一个比被接受的解决方案“简单得多”的解决方案。
泰勒达勒

25

这只是我找到的脚本,可在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;
};

最小化版本:

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

当文档准备好时,您必须调用它...

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

在Windows 7上于2012年3月28日在最新的FF,Chrome,IE和Safari中进行了测试,并且100%正常工作。

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


13
宽度将始终===在该代码中未定义。如果(true){...}
sstur

3
更正:width始终 ===未定义的第一时间的函数被调用。在width已经设置了对函数的后续调用时,该检查仅防止不必要地再次运行计算。
MartinAnsty

17
@MartinAnsty但是[width]变量是函数内部声明的,因此每次调用该函数时都会重新创建它。
MadSkunk

4
@MartinAnsty,如果您查看源代码,则在外部闭包中声明它。
TheCloudlessSky

3
只是为了加强通过@sstur和@TheCloudlessSky提出的观点,上面的代码是一样的一个在本Alman的插件,它不会缓存的结果width,而是重新计算每一次。它可以工作,但是效率很低。请帮个忙,在Alman的插件中使用正确的版本
hashchange

24

如果您正在寻找简单的操作,只需将纯dom js和jquery混合使用,

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

返回当前页面滚动条的大小。(如果可见,否则将返回0)


10
万一窗口没有滚动条(大显示器或小页面/应用程序),此操作将失败
Farid Nouri Neshat 2014年

1
这正是我想要的
azerafati 2015年

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

首先尝试了接受的答案,但发现在Windows 8的Firefox中该功能不再有效。切换到此变种,可以很好地完成工作。
Matijs 2014年

1
代码较短,但是浏览器必须重绘整个页面,因此非常慢。
阿德里安·梅尔2014年

11

对我来说,最有用的方法是

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

使用香草JavaScript。

在此处输入图片说明


谢谢@ stephen-kendy。一声问候。
安德烈斯·莫雷诺

3
正是我所需要的。一个建议:第二项可以用代替document.documentElement.clientWidthdocumentElement更清晰,干净地表达了获取<html>元素的意图。
Jan Miksovsky '18

9

我找到了一个简单的解决方案,该解决方案适用于页面内部的元素,而不是页面本身: $('#element')[0].offsetHeight - $('#element')[0].clientHeight

这将返回x轴滚动条的高度。


很棒的一个!您辛苦了:) y轴滚动条也可以使用“ .offsetWidth”和“ .clientWidth”。
Polosson

1
不幸的是,至少在宽度上似乎并不完全可靠。在Linux下的FireFox和Chrome中,.clientWidth似乎包括滚动条宽度的一半。
Michael Scheper 2014年

6

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

在我的网站上给我17,在Stackoverflow上给我14。


4

如果已经具有滚动条的元素,请使用:

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

如果没有horzintscrollbar,则该函数将调整为0


这是最好的答案。吻
乐队(Kiss)


3

的方式Antiscroll.js做它在它的代码是:

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

代码来自这里: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
    };
},

已在Chrome,FF,IE8,IE11中测试。


2

这应该可以解决问题,不是吗?

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

2

创建一个空的div并确保它出现在所有页面上(即,将其放入header模板中)。

给它这样的样式:

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

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

然后只需#scrollbar-helper使用Javascript 检查的大小:

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

不需要计算任何东西,因为这div总会有widthheightscrollbar

唯一的缺点是div您的模板中将有一个空白。但是,另一方面,您的Javascript文件会更干净,因为它只需要1或2行代码。


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

大多数浏览器将15px用作滚动条宽度


0

使用jQuery(仅在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;
}

但是我实际上更喜欢@Steve的答案。


0

这是一个很好的答案:https : //stackoverflow.com/a/986977/5914609

但是对于我来说,它没有用。我花了几个小时寻找解决方案。
最后,我返回到上面的代码,并为每种样式添加了!important。而且有效。
我无法在原始答案下方添加评论。因此,这里是解决方法:

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

这个终生的决定将使您有机会找到浏览器的scrollY宽度原始 JavaScript)。使用此示例,您可以在任何元素上获得scrollY宽度包括根据您当前的设计概念不需要滚动的那些元素:

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

这是基于偏移宽度差异的更简洁易读的解决方案:

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;

}

参见JSFiddle


0

已经在我的库中编码,因此它是:

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

我应该提到jQuery $(window).width()也可以代替window.document.documentElement.clientWidth

如果您在右侧的firefox中打开开发人员工具,则无法使用,但如果在底部打开了devs窗口,则可以克服该问题!

window.screen支持quirksmode.org

玩得开心!


0

似乎可行,但是也许有一个更简单的解决方案可以在所有浏览器中使用?

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.