检查HTML元素是否包含滚动条

时间:2011-02-02 21:59:25

标签: javascript dom scrollbar overflow

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

当然有一件事是检查元素是否大于其视口,这可以通过检查这两个值来轻松完成:

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

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

问题

如何检查 1 跨浏览器中的滚动条和 2 javascript(如 no jQuery )方式?

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

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

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

我想我必须检查overflow样式设置,但我该如何以跨浏览器的方式执行此操作?

其他编辑

不仅overflow样式设置。检查元素是否具有滚动条并不像看起来那么简单。我上面写的第一个公式在元素没有边框时工作正常,但是当它没有边框时(特别是当边框宽度相当大时),offset尺寸可能大于scroll尺寸但是元素仍然可以滚动。实际上,我们必须从offset维度中减去边框,以获取元素的实际可滚动视口,并将其与scroll维度进行比较。

供将来参考

:scrollable jQuery选择器过滤器包含在我的.scrollintoview() jQuery插件中。如果有人需要,我可以在我的blog post找到完整的代码。即使它没有提供实际的解决方案,Soumya的代码也大大帮助我解决了这个问题。它指出了我正确的方向。

11 个答案:

答案 0 :(得分:85)

几个星期前我发现了这个地方。它对我有用。

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

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

/* you'll get true/false */

答案 1 :(得分:16)

尝试:

对于垂直滚动条

  

el.scrollHeight> el.clientHeight

对于水平滚动条

  

el.scrollWidth> el.clientWidth

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

答案 2 :(得分:15)

这似乎(或是)有点hackish,但您可以测试scrollTopscrollLeft属性。

如果它们大于0,你知道有滚动条。如果它们为0,则将它们设置为1,然后再次测试它们以查看是否得到1的结果。然后将它们设置为0.

示例: 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

答案 3 :(得分:13)

这是另一种解决方案:

正如一些人所指出的,简单地比较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,
  };
}

答案 4 :(得分:6)

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

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

https://developer.mozilla.org/en/DOM/element.offsetWidth(第二张图片) https://developer.mozilla.org/en/DOM/element.clientWidth(第二张图片)

您需要检查:

  1. 是否使用计算/级联/当前样式将元素溢出设置为自动/滚动(包括overflowX / Y)。
  2. 如果元素的溢出设置为自动/滚动。建立offsetWidth和clientWidth。
  3. 如果clientWidth小于offsetWidth - 右边框(通过计算/级联/当前样式再次找到),则表示您有一个滚动条。
  4. 对垂直(offset / clientHeight)执行相同的操作。

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

    希望这有帮助!

答案 5 :(得分:1)

在这里乱搞,因为上述解决方案都没有为我(迄今为止)解决。 我将Div的scrollheight与其offsetHeight

进行比较后发现了一些成功
var oh = $('#wrapDiv').get(0).offsetHeight;
var sh = $('#wrapDiv').get(0).scrollHeight;

到目前为止,它似乎给了我一个精确的比较。有人知道这是否合法?

答案 6 :(得分:1)

在检查滚动条的存在时会出现一些问题,其中一个是在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;
};

答案 7 :(得分:1)

如果您需要了解整个网页是否存在滚动条,并且具有全面的浏览器支持,您可以使用以下方法:

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

使用window.innerHeight而不是document.body.clientHeight很重要,因为在某些移动浏览器中, clientHeight 不会获得地址栏的大小,而是 scrollHeight 会,所以您会得到错误的计算。

答案 8 :(得分:0)

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

Dim VeryLastRow2 As Long
With activesheet
    VeryLastRow2 = .Cells(.Rows.Count, "A").End(xlUp).Row
End With

这是因为IE报告当没有滚动条时scrollHeight比clientHeight大1但当滚动条存在时大约9更大

答案 9 :(得分:-4)

这些答案都不正确。你必须使用这个:

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

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

答案 10 :(得分:-6)

在其中添加100%宽的元素。然后将overflow设置为hidden。如果元素的计算样式(来自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];
}