如何计算滚动条的宽度?

Posted

技术标签:

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

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

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

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

有更好的方法吗?

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

【问题讨论】:

How can I get the browser's scrollbar sizes? 的可能重复项 【参考方案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;
;

【讨论】:

Google Closure Library 解决方案效果最好,谢谢! slickgrid 解决方案已损坏,请参阅github.com/6pac/SlickGrid/pull/149【参考方案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 中。即使文本区域为空白,这也会强制滚动条出现,因此宽度始终保持不变。

【讨论】:

以上是关于如何计算滚动条的宽度?的主要内容,如果未能解决你的问题,请参考以下文章

计算滚动条的宽度--js

EXCEL如何调整滚动条的宽度?

如何设置滚动条的宽度及颜色?

滚动条挤占内容宽度,影响布局

如何使用 CSS 增加滚动条的宽度?

如何在 WebEngineView 中调整滚动条的宽度?