2011-11-10 26 views
17

Dado un <textarea> con un width fijo, me gustaría que su "ancho activo" sea constante (en px). Por "ancho activo" me refiero al área donde aparece el texto.¿Cómo calcular el ancho de la barra de desplazamiento?

Cuando la barra de desplazamiento vertical no aparece, el "ancho activo" es igual a width. Pero, cuando aparece la barra de desplazamiento vertical, el "ancho activo" se vuelve más pequeño que width (creo que es más pequeño exactamente por el ancho de la barra de desplazamiento).

Pensé para identificar si la barra de desplazamiento vertical aparece o no, y si es así, para aumentar el ancho de <textarea> por el ancho de la barra de desplazamiento. ¿Cómo podría identificar el ancho de la barra de desplazamiento?

¿Hay un mejor enfoque?

(estoy interesado en Firefox, si se hace la vida más fácil.)

+1

posible duplicado de [¿Cómo puedo obtener tamaños de barra de desplazamiento del navegador?] (Http://stackoverflow.com/questions/986937/how-can-i-get-the -browsers-scrollbar-sizes) –

Respuesta

16

Hay un plugin de jQuery que puede ayudar con esto: https://github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/jquery.getscrollbarwidth.js

Asimismo, desde http://www.alexandre-gomes.com/?p=115 Aquí hay un código que puede ayudar.

Esto crea un elemento oculto <p> a la anchura de 100% dentro de un <div> con una barra de desplazamiento, a continuación, calcula el ancho <div> - la <p> width = ancho de la barra de desplazamiento.

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

Recibo el error "no puedo preparar la propiedad 'appendChild' of null" –

7

Tal vez usted podría poner

overflow-y:scroll; 

en el CSS. Esto fuerza a la barra de desplazamiento a estar presente incluso cuando el área de texto está en blanco, por lo que el ancho siempre es constante.

+0

Idea interesante ... –

0

Creo que esto ayuda a obtener el ancho de la barra de desplazamiento.

 
textarea.scrollHeight 

da la altura así que no puede ser utilizado este ..

+0

¿Has probado esto? Cuando la barra de desplazamiento no aparece, todavía devuelve un valor distinto de cero. –

8

Ancho de la barra de desplazamiento es simplemente (offsetWidth - clientWidth) sin bordes! elemento. Esta función lo calcula sobre la marcha y guarda el resultado en caché para un uso posterior. No es necesario un porcentaje de ancho, 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; 
}; 
2

que estaba buscando algo similar - que aquí es lo que encontré

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

Fuente: Slickgrid utiliza este - https://github.com/mleibman/SlickGrid/blob/master/slick.grid.js#L378

O

Uso Google Biblioteca Cierre - 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; 
}; 
+0

la solución de biblioteca de Google Closure funciona mejor, ¡gracias! la solución slickgrid está rota, consulte https://github.com/6pac/SlickGrid/pull/149 – kofifus

2

Usando jQuery, simplemente escriba:

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

Devuelve "NaN" - Chrome 54 –

+0

¿Está seguro? Parece devolver 0 para mí porque las nuevas barras de desplazamiento de Chrome no ocupan espacio –

0

CSS:

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

vainilla 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

0

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

ancho de la barra = 18

Cuestiones relacionadas