What\'s the fastest way of checking whether an element has scroll bars?
One thing of course is checking whether element is larger than its viewport, which can easily
Add an 100% wide element inside it. Then set overflow to hidden. If the element's computed style (from jQ) changes, the parent had a scrollbar.
EDIT: It seems you want a cross browser method like getComputedStyle. Try:
function getCSS(_elem, _style)
{
var computedStyle;
if (typeof _elem.currentStyle != 'undefined')
computedStyle = _elem.currentStyle;
else
computedStyle = document.defaultView.getComputedStyle(_elem, null);
return computedStyle[_style];
}
I found this somewhere a couple of weeks ago. It worked for me.
var div = document.getElementById('container_div_id');
var hasHorizontalScrollbar = div.scrollWidth > div.clientWidth;
var hasVerticalScrollbar = div.scrollHeight > div.clientHeight;
/* you'll get true/false */
For IE11 (Internet Explorer 11) I had to change the logic to:
// Subtract 3 (a small arbitrary number) to allow for IE reporting a difference of 1 when no scrollbar is present
var hasVerticalScrollbar = div.scrollHeight - 3 > div.clientHeight;
This is because IE reports scrollHeight as 1 larger than clientHeight when no scrollbar is present but approx 9 larger when a scrollbar is present
I maybe a little late to the party, but...
I believe you can detect for scrollbars with e.offsetWidth vs. e.clientWidth. Offset width includes borders and scrollbars, padding and width. Client width includes padding and width. Please see:
https://developer.mozilla.org/en/DOM/element.offsetWidth (second image) https://developer.mozilla.org/en/DOM/element.clientWidth (second image)
You need to check:
Do the same for the vertical (offset/clientHeight).
IE7 reports a clientHeight of 0 for some elements (I haven't checked why), therefore you always need the first overflow check.
Hope this helps!
Here is yet another solution:
As a few people pointed out, simply comparing offsetHeight and scrollHeight is not enough since they differ on elements with overflow hidden, etc., that still don't have scrollbars. So here I'm also checking if overflow is scroll or auto on the computed styles for the element:
var isScrollable = function(node) {
var overflowY = window.getComputedStyle(node)['overflow-y'];
var overflowX = window.getComputedStyle(node)['overflow-x'];
return {
vertical: (overflowY === 'scroll' || overflowY === 'auto') && node.scrollHeight > node.clientHeight,
horizontal: (overflowX === 'scroll' || overflowX === 'auto') && node.scrollWidth > node.clientWidth,
};
}
This may seem (or be) a little hackish, but you could test the scrollTop
and scrollLeft
properties.
If they're greater than 0, you know there are scrollbars. If they're 0, then set them to 1, and test them again to see if you get a result of 1. Then set them back to 0.
Example: http://jsfiddle.net/MxpR6/1/
function hasScroll(el, direction) {
direction = (direction === 'vertical') ? 'scrollTop' : 'scrollLeft';
var result = !! el[direction];
if (!result) {
el[direction] = 1;
result = !!el[direction];
el[direction] = 0;
}
return result;
}
alert('vertical? ' + hasScroll(document.body, 'vertical'));
alert('horizontal? ' + hasScroll(document.body, 'horizontal'));
I believe there's a different property for IE, so I'll update in a minute with that.
EDIT: Appears as though IE may support this property. (I can't test IE right now.)
http://msdn.microsoft.com/en-us/library/ms534618(VS.85).aspx