Подтвердить что ты не робот

Как рассчитать ширину полосы прокрутки?

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

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

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

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

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

4b9b3361

Ответ 1

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

Кроме того, из http://www.alexandre-gomes.com/?p=115 Вот какой код может помочь.

Это создает скрытый элемент <p> со 100% шириной внутри <div> с полосой прокрутки, затем вычисляет ширину <div> - ширину полосы <p> 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); 
}; 

Ответ 2

Ширина полосы прокрутки просто (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;
};

Ответ 3

Возможно, вы могли бы поставить

overflow-y:scroll;

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

Ответ 4

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

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

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

Ответ 5

Используя 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;
};

Ответ 6

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

textarea.scrollHeight

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

Ответ 7

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

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

Ответ 8

С помощью 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

Ответ 9

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

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