【问题标题】: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

标签: javascript scrollbar


【解决方案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 类。
  • 是的,我得到了相同的谷歌结果。 :) 我正在努力让您了解情况。
  • 如果您将主题更改为具有不同大小滚动条的主题,计算与实际的偏差是多少?
  • 参见此处进行交叉引用:stackoverflow.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.clientWidthdocumentElement 更清晰干净地表达了获取&lt;html&gt; 元素的意图。
  • 如果您使用 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,在 Stackoverflow 上给我 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 将始终具有scrollbarwidthheight

          唯一的缺点是您的模板中会有一个空的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://stackoverflow.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.screenquirksmode.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";
                              

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2014-09-07
                                • 1970-01-01
                                • 2010-09-06
                                • 2018-08-31
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多