【问题标题】:How to calculate the width of the scroll bar?如何计算滚动条的宽度?
【发布时间】:2011-12-26 02:57:42
【问题描述】:

给定一个带有固定width<textarea>,我希望它的“活动宽度”保持不变(在px 中)。 “活动宽度”是指文本出现的区域。

当垂直滚动条不出现时,“活动宽度”等于width。但是,当垂直滚动条出现时,“活动宽度”变得小于width(我猜正好是滚动条的宽度)。

我想确定垂直滚动条是否出现,如果出现,则将<textarea>的宽度增加滚动条的宽度。如何识别滚动条的宽度?

有更好的方法吗?

(我对 Firefox 很感兴趣,如果它能让生活更轻松的话。)

【问题讨论】:

标签: javascript html width scrollbar


【解决方案1】:

我相信这是一个更直接的解决方案:(假设body {width:100%;}

function calculateScrollBarWidth() {
  return window.innerWidth - document.body.clientWidth;
}

计算任何元素的滚动条宽度的解决方案(例如,带有溢出的 div 或 textarea)

function calculateScrollbarWidth(element) {
  if (!element) {
    // Return the body scrollbar width, when no element was specified.
    return window.innerWidth - document.body.clientWidth;
  } else {
    // When an element is specified, return its specific scrollbar width.
    return element.offsetWidth - element.clientWidth;
  }
}

【讨论】:

  • 这应该是公认的答案
  • 完美解决方案!这是另一个关于如何计算任何元素(不仅是正文)的滚动条宽度的示例:javascripttutorial.net/dom/css/…
  • 对我来说,使用 Chrome 版本 89,window.innerWidth & document.documentElement.clientWidth 返回相同的值
【解决方案2】:

使用 jQuery:

var t = jQuery('<textarea/>').css({
    position: 'absolute', 
    top: '-100px',
    overflowX: 'hidden',
    overflowY: 'scroll'
}).prependTo('body'),
w = t[0].offsetWidth - t[0].clientWidth;
console.log('bar width = ', w);
t.remove();

条宽 = 18

【讨论】:

    【解决方案3】:

    CSS:

    .scrollbar-measure {
      width: 100px;
      height: 100px;
      overflow: scroll;
      position: absolute;
      top: -9999px;
    }
    

    原版JS:

    // 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.warn(scrollbarWidth); // Mac:  15
    
    // Delete the DIV 
    document.body.removeChild(scrollDiv);
    

    Solution by David Walsh

    【讨论】:

      【解决方案4】:

      使用jQuery,简单写:

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

      【讨论】:

      • 返回“NaN” - Chrome 54
      • 你确定吗?它似乎为我返回 0,因为 Chrome 的新滚动条不占用空间
      【解决方案5】:

      我正在寻找类似的东西 - 这是我找到的东西

       function measureScrollbar() {
            var $c = $("<div style='position:absolute; top:-10000px; left:-10000px; width:100px; height:100px; overflow:scroll;'></div>").appendTo("body");
            var dim = {
              width: $c.width() - $c[0].clientWidth,
              height: $c.height() - $c[0].clientHeight
            };
            $c.remove();
            return dim;
          }
      

      来源:Slickgrid 使用这个 - https://github.com/mleibman/SlickGrid/blob/master/slick.grid.js#L378

      或者

      使用 Google Closure 库 -link

      /**
       * Returns the scroll bar width (represents the width of both horizontal
       * and vertical scroll).
       *
       * @param {string=} opt_className An optional class name (or names) to apply
       *     to the invisible div created to measure the scrollbar. This is necessary
       *     if some scrollbars are styled differently than others.
       * @return {number} The scroll bar width in px.
       */
      goog.style.getScrollbarWidth = function(opt_className) {
        // Add two hidden divs.  The child div is larger than the parent and
        // forces scrollbars to appear on it.
        // Using overflow:scroll does not work consistently with scrollbars that
        // are styled with ::-webkit-scrollbar.
        var outerDiv = goog.dom.createElement('div');
        if (opt_className) {
          outerDiv.className = opt_className;
        }
        outerDiv.style.cssText = 'overflow:auto;' +
            'position:absolute;top:0;width:100px;height:100px';
        var innerDiv = goog.dom.createElement('div');
        goog.style.setSize(innerDiv, '200px', '200px');
        outerDiv.appendChild(innerDiv);
        goog.dom.appendChild(goog.dom.getDocument().body, outerDiv);
        var width = outerDiv.offsetWidth - outerDiv.clientWidth;
        goog.dom.removeNode(outerDiv);
        return width;
      };
      

      【讨论】:

      【解决方案6】:

      滚动条的宽度简直就是(offsetWidth - clientWidth)中的一个无边框!元素。 此函数即时计算并缓存结果以供进一步使用。不需要百分比宽度等。

      var getScrollbarWidth = function() {
        var div, width = getScrollbarWidth.width;
        if (width === undefined) {
          div = document.createElement('div');
          div.innerHTML = '<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>';
          div = div.firstChild;
          document.body.appendChild(div);
          width = getScrollbarWidth.width = div.offsetWidth - div.clientWidth;
          document.body.removeChild(div);
        }
        return width;
      };
      

      【讨论】:

        【解决方案7】:

        有一个 jQuery 插件可以帮助解决这个问题:https://github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/jquery.getscrollbarwidth.js

        另外,来自http://www.alexandre-gomes.com/?p=115 这是一些可能有帮助的代码。

        这会在带有滚动条的 &lt;div&gt; 内创建一个 100% 宽度的隐藏 &lt;p&gt; 元素,然后计算 &lt;div&gt; 宽度 - &lt;p&gt; 宽度 = 滚动条宽度。

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

        【讨论】:

        • 我收到错误“无法准备好属性 'appendChild' of null”
        【解决方案8】:

        我认为这有助于获得滚动条的宽度。

        textarea.scrollHeight

        给出了高度,所以不能用这个..

        【讨论】:

        • 你测试过这个吗?当滚动条没有出现时,它仍然返回一个非零值。
        【解决方案9】:

        也许你可以放

        overflow-y:scroll;
        

        在你的 CSS 中。即使文本区域为空白,这也会强制滚动条出现,因此宽度始终保持不变。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-13
          • 2012-06-04
          • 1970-01-01
          • 2012-08-31
          • 1970-01-01
          相关资源
          最近更新 更多