web-dev-qa-db-fra.com

Comment calculer la largeur de la barre de défilement?

Étant donné un <textarea> avec une width fixe, je voudrais que sa "largeur active" soit constante (dans px). Par "largeur active", j'entends la zone où le texte apparaît.

Lorsque la barre de défilement verticale n'apparaît pas, la "largeur active" est égale à width. Mais, lorsque la barre de défilement verticale apparaît, la "largeur active" devient inférieure à width (je suppose plus petite exactement de la largeur de la barre de défilement).

J'ai pensé identifier si la barre de défilement verticale apparaît ou non, et si oui, augmenter la largeur du <textarea> de la largeur de la barre de défilement. Comment identifier la largeur de la barre de défilement?

Est-ce qu'il y a une meilleure approche?

(Je suis intéressé par Firefox, si cela facilite la vie.)

17
Misha Moroshko

Il existe un plugin jQuery qui peut aider avec ceci: https://github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/jquery.getscrollbarwidth.js

Aussi, à partir de http://www.alexandre-gomes.com/?p=115 Voici du code qui pourrait vous aider. 

Cela crée un élément <p> masqué à 100% de la largeur dans un <div> avec une barre de défilement, puis calcule la largeur <div> - le <p> width = largeur de la barre de défilement. 

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); 
}; 
16
David Houde

La largeur de la barre de défilement est simplement (offsetWidth - clientWidth) dans un environnement sans bordure! element. Cette fonction le calcule à la volée et en cache le résultat pour une utilisation ultérieure. Pas besoin de pourcentage de largeur, etc.

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

Peut-être que vous pourriez mettre

overflow-y:scroll;

dans vos css. Cela force la barre de défilement à être présente même lorsque la zone de texte est vide, ainsi la largeur est toujours constante.

7
Oliver

Je cherchais quelque chose de similaire - voici ce que j'ai trouvé 

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

Source: Slickgrid utilise this - https://github.com/mleibman/SlickGrid/blob/master/slick.grid.js#L378

Ou 

Utiliser la bibliothèque 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;
};
2
dekdev

Avec jQuery, écrivez simplement:

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
Joshua Bambrick

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

Solution de David Walsh

0
max

Je pense que cela aide à obtenir la largeur de la barre de défilement.

 textarea.scrollHeight 

donne la hauteur alors ne peut pas être utilisé ..

0
Sudhir Bastakoti

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

largeur de la barre = 18

0
ekerner