Как рассчитать ширину полосы прокрутки? - PullRequest
20 голосов
/ 10 ноября 2011

Учитывая <textarea> с фиксированным width, я бы хотел, чтобы его "активная ширина" была постоянной (в px).Под «активной шириной» я подразумеваю область, где появляется текст.

Когда вертикальная полоса прокрутки не появляется, «активная ширина» равна width.Но когда появляется вертикальная полоса прокрутки, «активная ширина» становится меньше, чем width (я думаю, она будет меньше точно по ширине полосы прокрутки).

Я подумал, чтобы определить, появляется ли вертикальная полоса прокруткиили нет, и если да, увеличить ширину <textarea> на ширину полосы прокрутки.Как определить ширину полосы прокрутки?

Есть ли лучший подход?

(мне интересен Firefox, если он облегчит жизнь.)

Ответы [ 9 ]

16 голосов
/ 10 ноября 2011

Существует плагин jQuery, который может помочь с этим: https://github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/jquery.getscrollbarwidth.js

Также из http://www.alexandre -gomes.com /? P = 115 Вот код, который можетПомогите.

Это создает скрытый элемент <p> с шириной 100% внутри <div> с полосой прокрутки, а затем вычисляет <div> width - <p> width = width полосы прокрутки.

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); 
}; 
9 голосов
/ 27 мая 2013

Ширина полосы прокрутки просто (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 голосов
/ 10 ноября 2011

Может быть, вы могли бы поставить

overflow-y:scroll;

в вашем CSS.Это заставляет полосу прокрутки присутствовать, даже когда текстовая область пуста, поэтому ширина всегда постоянна.

2 голосов
/ 22 августа 2014

Используя 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;
};
2 голосов
/ 10 января 2014

Я искал что-то подобное - вот что я нашел

 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 - ссылка

/**
 * 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;
};
1 голос
/ 24 мая 2019

Я считаю, что это более простое решение: (при условии body {width:100%;})

function calculateScrollBarWidth() {
  return window.innerWidth - document.body.clientWidth;
}
0 голосов
/ 13 августа 2017

С 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

0 голосов
/ 24 января 2017

CSS:

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

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

Решение Дэвида Уолша

0 голосов
/ 10 ноября 2011

Я думаю, что это помогает получить ширину полосы прокрутки.

textarea.scrollHeight

дает высоту, так что это не может быть использовано ..

...