如何获取浏览器的滚动条大小?
Posted
技术标签:
【中文标题】如何获取浏览器的滚动条大小?【英文标题】:How can I get the browser's scrollbar sizes? 【发布时间】:2010-11-02 11:36:27 【问题描述】:如何在 javascript 中确定水平滚动条的高度或垂直滚动条的宽度?
【问题讨论】:
这里是来自 JQuery Dimension 插件作者的 sn-p。 github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/… 给出这个解决方案可能晚了,但对我来说,这似乎是一个更好的解决方案,IMO。 看看这个解决方案:davidwalsh.name/detect-scrollbar-width @GibboK -- 该解决方案失败 -- offsetWidth == clientWidth 所以它总是为零。这是在边缘 IE && Chrome 中测试的。 @beauXjames 很奇怪它在 FF 上对我有用 这个问题出现在滚动条位置错误(屏幕中间某处)的情况下。在这种情况下,您可能不想显示滚动条。在大多数情况下,我发现 iScroll 是解决这种情况的完美设计中立解决方案:iscrolljs.com 【参考方案1】:来自Alexandre Gomes Blog 没试过。让我知道它是否适合你。
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);
;
【讨论】:
这个想法是天才,我肯定会在此基础上制作一个 MooTools 类。 是的,我得到了相同的谷歌结果。 :) 我正在努力让您了解情况。 如果您将主题更改为具有不同大小滚动条的主题,计算与实际的偏差是多少? 参见此处进行交叉引用:***.com/questions/3417139/… 返回具有不同页面缩放的不同值。 Win7、Opera、FF。【参考方案2】:使用 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;
;
【讨论】:
谢谢,这个解决方案很干净!! 如果将 JQuery 的整个源代码复制粘贴到它之前,这个解决方案真的会感觉更干净吗?因为这几乎就是这个解决方案正在做的事情。这个问题在 JQuery 中没有要求答案,完全有可能在不使用库的情况下执行此任务并且高效。 如果你已经在使用 JQuery,那么 Daemon 的注释是无关紧要的。是的,添加 JQuery 只是为了做到这一点是无稽之谈,但对于那些已经在他们的项目中使用 JQuery 的人来说,这是一个比公认的更“简单”的解决方案。【参考方案3】:如果你在寻找一个简单的操作,只需混合普通的 dom js 和 jquery,
var swidth=(window.innerWidth-$(window).width());
返回当前页面滚动条的大小。 (如果可见,否则返回0)
【讨论】:
如果窗口没有滚动条(大显示器或小页面/应用程序),这将失败 这正是我想要的 对于我们这些不使用 jQuery 的人来说,$(element).width()
是做什么的?没有jQuery怎么写?【参考方案4】:
这是我找到的唯一一个脚本,它在 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()); );
于 2012 年 3 月 28 日在 Windows 7 上使用最新的 FF、Chrome、IE 和 Safari 进行测试,并且 100% 正常工作。
来源:http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
【讨论】:
width 将始终 === 在该代码中未定义。 if (true) ... 更正:width
将总是 ===未定义第一次函数被调用。在随后调用函数width
时已经设置,该检查只是防止不必要地再次运行计算。
@MartinAnsty 但是 [width] 变量是在函数内部声明的,因此每次调用函数时都会重新创建它。
@MartinAnsty,如果您查看source,它是在外部闭包中声明的。
只是为了强调@sstur 和@TheCloudlessSky 的观点,上面的代码与Ben Alman 的插件中的代码不相同,它不会缓存结果在width
中,而是每次都重新计算。它有效,但效率极低。请帮世界一个忙,在 Alman 的插件中使用 correct version。【参考方案5】:
对我来说,最有用的方法是
(window.innerWidth - document.getElementsByTagName('html')[0].clientWidth)
使用原生 JavaScript。
【讨论】:
谢谢@stephen-kendy。问候。 正是我所需要的。一个建议:第二个词可以换成document.documentElement.clientWidth
。 documentElement
更清晰干净地表达了获取<html>
元素的意图。
如果您使用 JS,最好、最简单的解决方案!【参考方案6】:
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;
【讨论】:
首先尝试了accepted answer,但发现它在 Windows 8 上的 Firefox 中不再适用。切换到此变体,效果很好。 代码比较短,但是浏览器要重绘整个页面,所以很慢。【参考方案7】:我找到了一个简单的解决方案,它适用于页面内部的元素,而不是页面本身:
$('#element')[0].offsetHeight - $('#element')[0].clientHeight
这将返回 x 轴滚动条的高度。
【讨论】:
伟大的!你成就了我的一天 :) 对于 y 轴滚动条,“.offsetWidth”和“.clientWidth”也同样适用。 不幸的是,至少对于宽度而言,这似乎并不完全可靠。 .clientWidth 似乎包括 Linux 下 FireFox 和 Chrome 中滚动条宽度的一半。【参考方案8】:来自David Walsh's blog:
// 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,在 *** 上给我 14。
【讨论】:
【参考方案9】:您可以使用 jquery + javascript 确定 window
滚动条和 document
如下:
var scrollbarWidth = ($(document).width() - window.innerWidth);
console.info("Window Scroll Bar Width=" + scrollbarWidth );
【讨论】:
请注意,innerWidth 适用于 IE9+。否则很好的解决方案。【参考方案10】:这应该可以解决问题,不是吗?
function getScrollbarWidth()
return (window.innerWidth - document.documentElement.clientWidth);
【讨论】:
【参考方案11】:如果您已经有一个带有滚动条的元素,请使用:
function getScrollbarHeight(el)
return el.getBoundingClientRect().height - el.scrollHeight;
;
如果不存在horzintscrollbar,该函数将返回0
【讨论】:
这是最好的答案。吻。规则所有【参考方案12】: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
【讨论】:
【参考方案13】: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 中测试。
【讨论】:
【参考方案14】:function getScrollBarWidth()
return window.innerWidth - document.documentElement.clientWidth;
大多数浏览器使用 15px 作为滚动条宽度
【讨论】:
当然,这只有在滚动条已经可见的情况下才有效。有时我们需要在显示之前预测大小。此外,移动浏览器不使用 15px 作为滚动条。【参考方案15】:创建一个空的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;
然后只需使用 Javascript 检查#scrollbar-helper
的大小:
var scrollbarWidth = document.getElementById('scrollbar-helper').offsetWidth;
var scrollbarHeight = document.getElementById('scrollbar-helper').offsetHeight;
无需计算任何内容,因为此div
将始终具有scrollbar
的width
和height
。
唯一的缺点是您的模板中会有一个空的div
。但另一方面,您的 Javascript 文件会更干净,因为这只需要 1 或 2 行代码。
【讨论】:
【参考方案16】: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;
【讨论】:
【参考方案17】:使用 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 的回答。
【讨论】:
【参考方案18】:这是一个很好的答案: https://***.com/a/986977/5914609
但是在我的情况下它不起作用。我花了几个小时寻找解决方案。 最后我回到了上面的代码并添加了 !important 到每种样式。它奏效了。 我无法在原始答案下方添加 cmets。所以这里是修复:
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);
;
【讨论】:
【参考方案19】:这个生命黑客决定会让你有机会找到浏览器滚动宽度(原版 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;
【讨论】:
【参考方案20】:这里是基于偏移宽度差异的更简洁易读的解决方案:
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。
【讨论】:
【参考方案21】:已经在我的库中编码,所以这里是:
var vScrollWidth = window.screen.width - window.document.documentElement.clientWidth;
我应该提一下,jQuery $(window).width()
也可以用来代替window.document.documentElement.clientWidth
。
如果你在右边的firefox中打开开发者工具,它不起作用,但如果在底部打开开发者窗口,它就会克服它!
支持window.screen
quirksmode.org!
玩得开心!
【讨论】:
【参考方案22】:似乎可行,但也许有一个更简单的解决方案适用于所有浏览器?
// 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;
【讨论】:
【参考方案23】:我制作了@Matthew Vines 答案的更新版本。
它更容易阅读,更容易理解。它不需要内部元素。为获取滚动条宽度而创建的元素具有 100% 的高度/宽度,因此它不会在低端 PC/手机的主体上创建任何可见的滚动条,这可能需要更多时间来创建元素,获取宽度,最后移除元素。
const getScrollBarWidth = () =>
const e = document.createElement('div');
Object.assign(e.style,
width: '100%',
height: '100%',
overflow: 'scroll',
position: 'absolute',
visibility: 'hidden',
top: '0',
left: '0',
);
document.body.appendChild(e);
const scrollbarWidth = e.offsetWidth - e.clientWidth;
document.body.removeChild(e);
return scrollbarWidth;
;
console.log(getScrollBarWidth());
我确实建议只检查一次滚动条宽度,在页面加载时(除非它不符合您的需要),然后将结果存储在状态/变量中。
【讨论】:
【参考方案24】:我在 material-ui
代码中找到了该解决方案,它对我有用。
const scrollbarWidth = window.innerWidth - document.querySelector('body').clientWidth;
【讨论】:
【参考方案25】:您可以使用此解决方案来查找网页内任何元素的滚动条宽度,而不是网页本身。您还可以通过将其与宽度相关的属性替换为与高度相关的对应属性,将其重写为在水平滚动条的情况下适用于滚动条高度。
offsetWidth
属性返回内容、内边距、边框和滚动条(如果有的话)的总宽度。而clientWidth
属性仅返回内容和填充的总宽度。
所以,如果我们从offsetWidth
中减去clientWidth
和水平边框,我们将得到滚动条的宽度。也就是说,如果有滚动条,我们就会得到滚动条的宽度。但是如果没有滚动条,我们会得到0
。
const element = document.querySelector("div");
const elementStyle = window.getComputedStyle(element);
const horizontalBorder = parseFloat(elementStyle.borderLeftWidth) + parseFloat(elementStyle.borderRightWidth);
const scrollbarWidth = element.offsetWidth - element.clientWidth - horizontalBorder + "px";
【讨论】:
以上是关于如何获取浏览器的滚动条大小?的主要内容,如果未能解决你的问题,请参考以下文章