检查 HTML 元素是否有滚动条

检查元素是否有滚动条的最快方法是什么?

当然,一件事情是检查元素是否大于它的 viewport,这可以通过检查这两个值很容易地完成:

el.scrollHeight > el.offsetHeight || el.scrollWidth > el.offsetWidth

但这并不意味着它也有滚动条(所以它实际上可以被人类滚动)。

提问

我如何检查滚动条在 1跨浏览器和 2 javascript 只(如在 没有 jQuery)的方式?

仅使用 Javascript,因为我需要尽可能小的开销,因为我想编写一个非常快的 jQuery 选择器过滤器

// check for specific scrollbars
$(":scrollable(x/y/both)")


// check for ANY scrollbar
$(":scrollable")

我想我必须检查 overflow样式设置,但是我如何在跨浏览器的方式做到这一点?

附加编辑

不仅仅是 overflow样式设置。检查一个元素是否有滚动条并不像看起来那么简单。上面我写的第一个公式在元素没有边框的情况下可以很好地工作,但是当元素有边框的时候(特别是当边框很宽的时候) ,offset维可以比 scroll维大,但是元素仍然可以滚动。实际上,我们必须从 offset维度中减去边框,才能得到元素的实际可滚动视图,并将其与 scroll维度进行比较。

以备将来参考

我的 .scrollintoview() jQuery 插件中包含了 :scrollable jQuery 选择器过滤器。完整的代码可以找到在我的 博客文章如果有人需要它。尽管它没有提供实际的解决方案,但 Soumya 的代码相当大地帮助我解决了这个问题。它为我指明了正确的方向。

115040 次浏览

在其中添加一个100% 宽的元素。然后将溢出设置为隐藏。如果元素的计算样式(来自 jQ)发生变化,则父元素有一个滚动条。

编辑: 看起来你想要一个像 GetComputedStyle这样的跨浏览器方法。试试:

function getCSS(_elem, _style)
{
var computedStyle;
if (typeof _elem.currentStyle != 'undefined')
computedStyle = _elem.currentStyle;
else
computedStyle = document.defaultView.getComputedStyle(_elem, null);
return computedStyle[_style];
}

试试:

垂直滚动条

El.scrollHeight > el.clientHeight

用于水平滚动条

El.scrollWidth > el.clientWidth

我知道这至少适用于 IE8和 Firefox 3.6 + 。

这可能看起来有点像 (或生存),但是您可以测试 scrollTopscrollLeft的属性。

如果它们大于0,就会有滚动条。如果它们是0,那么将它们设置为1,然后再次测试它们,看看是否得到1的结果。然后把它们设置回0。

示例: < a href = “ http://jsfiddle.net/MxpR6/1/”rel = “ noReferrer”> 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'));

我相信 IE 有一个不同的属性,所以我将在一分钟内更新。

编辑: 看起来 IE 可能支持这个属性。(我现在不能测试 IE。)

Http://msdn.microsoft.com/en-us/library/ms534618(vs.85).aspx

几周前我在某个地方发现了这个,对我很有用。

var div = document.getElementById('container_div_id');


var hasHorizontalScrollbar = div.scrollWidth > div.clientWidth;
var hasVerticalScrollbar = div.scrollHeight > div.clientHeight;


/* you'll get true/false */

我可能有点迟到了,但是..。

我相信您可以使用 e.offsetWidth 和 e.clientWidth 检测滚动条。偏移宽度包括边框和滚动条、填充和宽度。客户端宽度包括填充和宽度。请参阅:

Https://developer.mozilla.org/en/dom/element.offsetwidth (第二张图片) Https://developer.mozilla.org/en/dom/element.clientwidth (第二张图片)

你需要检查:

  1. 元素是否使用计算/级联/当前样式将溢出设置为自动/滚动(包括溢出 X/Y)。
  2. 如果元素确实有溢出,则设置为 auto/rolll.offsetWidth 和 clientWidth。
  3. 如果 clientWidth 小于 offsetWidth-right 边框(通过计算/级联/当前样式再次找到) ,那么您就知道您有一个滚动条。

对垂直方向(偏移量/clientHeight)执行相同操作。

IE7报告某些元素的 clientHeight 为0(我还没有检查为什么) ,因此您总是需要进行第一次溢出检查。

希望这个能帮上忙!

只是在这里胡闹,因为上面的解决方案没有一个适合我(到目前为止)。 我已经找到了一些成功的比较 Div 的滚动高度和它的偏移高度

var oh = $('#wrapDiv').get(0).offsetHeight;
var sh = $('#wrapDiv').get(0).scrollHeight;

目前看来,这个比较很准确,有人知道这是否合法吗?

这里还有另一个解决方案:

正如一些人指出的那样,仅仅比较 offsetHeight 和 scrollHeight 是不够的,因为它们在没有滚动条的溢出隐藏等元素上存在差异。这里我还检查了溢出是滚动还是自动执行元素的计算样式:

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

没有一个答案是正确的,你必须用这个:

var div = document.getElementById('container_div_id');


var hasHorizontalScrollbar = (div.offsetWidth > div.clientWidth);
var hasVerticalScrollbar = (div.offsetHeight > div.clientHeight);

对于 IE11(Internet Explorer 11) ,我不得不改变逻辑:

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

这是因为 IE 在没有滚动条时报告的 scrollHeight 比 clientHeight 大1,而在有滚动条时报告的 scrollHeight 比 clientHeight 大约9

在检查滚动条是否存在的情况下有几个问题,其中之一是在 mac 中没有任何可见的滚动条,因此上面的所有解决方案都不会给你一个准确的答案。

因为浏览器的渲染不是很频繁,所以你可以通过改变滚动条来检查有没有滚动条,然后再把它设置回去:

const hasScrollBar = (element) => {
const {scrollTop} = element;


if(scrollTop > 0) {
return true;
}


element.scrollTop += 10;


if(scrollTop === element.scrollTop) {
return false;
}


// undoing the change
element.scrollTop = scrollTop;
return true;
};

如果你想知道 整个网页完全支持浏览器是否有一个滚动条,你可以使用以下方法:

const hasScrollbar = document.body.scrollHeight > window.innerHeight

使用 window.innerHeight而不是 document.body.clientHeight非常重要,因为在一些移动浏览器中,客户身高不会得到地址栏的大小,但是 高度会,所以你得到了错误的计算结果。

是不是为水平滚动条它将是基于高度计算的东西喜欢

element.offsetHeight - element.clientHeight

总之,对于水平滚动条,要进行基于高度的计算,对于垂直滚动条,反之亦然。