检查HTML元素是否有滚动条

发布于 2024-10-15 18:20:21 字数 1154 浏览 6 评论 0原文

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

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

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 维度进行比较。

供将来参考

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

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 be done by checking these two values:

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

but that doesn't mean that it has scrollbars as well (so it can actually be scrolled by humans).

Question

How do I check for scrollbars in a 1 cross browser and 2 javascript only (as in no jQuery) way?

Javascript only, because I need as small overhead as possible, because I'd like to write a very fast jQuery selector filter

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

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

I suppose I'd have to check for overflow style settings but how do I do that in a cross browser way?

Additional edit

Not only overflow style settings. Checking whether an element has a scrollbar isn't as trivial as it seems. The first formula I've written above works fine when element doesn't have a border, but when it does (especially when border is of considerable width), offset dimension can be larger than scroll dimension but the element can still be scrollable. We actually have to subtract borders from offset dimension to get the actual scrollable viewport of the element and compare that to scroll dimension.

For future reference

:scrollable jQuery selector filter is included in my .scrollintoview() jQuery plugin. Complete code can be found in my blog post if anybody needs it. Even though it didn't provide the actual solution Soumya's code considerably helped me solve the problem. It pointed me in the right direction.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

心不设防 2024-10-22 18:20:22

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

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

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

/* you'll get true/false */

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 */
独木成林 2024-10-22 18:20:22

这可能看起来(或者是)有点 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

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

万人眼中万个我 2024-10-22 18:20:22

尝试:

对于垂直滚动条

el.scrollHeight > el.clientHeight

用于水平滚动条

el.scrollWidth > el.clientWidth

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

Try:

For vertical scroll bar

el.scrollHeight > el.clientHeight

For horizontal scrollbar

el.scrollWidth > el.clientWidth

I know this works for IE8 and Firefox 3.6+ at least.

失眠症患者 2024-10-22 18:20:22

这是另一个解决方案:

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

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,
  };
}
瞄了个咪的 2024-10-22 18:20:22

我可能有点晚了,但是...

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

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

您需要检查:

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

对垂直方向(偏移量/客户端高度)执行相同的操作。

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

希望这有帮助!

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:

  1. Whether or not the element has overflow set to auto/scroll (including overflowX/Y) using the computed/cascaded/current style.
  2. If the element does have overflow set to auto/scroll. Establish the offsetWidth and clientWidth.
  3. If the clientWidth is less than the offsetWidth - right border (found again through the computed/cascaded/current style), then you know you have a scrollbar.

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!

请持续率性 2024-10-22 18:20:22

在检查滚动条是否存在时会遇到几个问题,其中之一是在 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;
};

There are several problems in case of checking the existence of scrollbars one of which is that in mac you don't have any visible scrollbar so both all the solutions above wouldn't give you an accurate answer.

So because the browser's rendering isn't very frequent you can check the having scroll with changing scroll and then setting it back:

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

巴黎盛开的樱花 2024-10-22 18:20:22

如果您需要知道整个网页是否存在滚动条并且完整的浏览器支持,您可以使用以下内容:

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

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

If you need to know if theres a scrollbar present for the whole webpage and with full browser support you can use this:

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

It's important to use window.innerHeight instead of document.body.clientHeight because in some mobile browsers clientHeight will not get the size of the address bar but scrollHeight will, so you get wrong calculations.

沦落红尘 2024-10-22 18:20:22

此函数接受一个元素和一个方向(verticalhorizo​​ntalboth)作为参数并返回 true如果元素在指定方向上有滚动条,否则为 false

function hasScrollbar(el, direction = 'both') {
  const style = window.getComputedStyle(el);
  if (direction === 'vertical' || direction === 'both') {
    if (el.clientHeight < el.scrollHeight || style.overflowY === 'scroll' || style.overflowY === 'auto') {
      return true;
    }
  }

  if (direction === 'horizontal' || direction === 'both') {
    if (el.clientWidth < el.scrollWidth || style.overflowX === 'scroll' || style.overflowX === 'auto') {
      return true;
    }
  }

  return false;
}

输入图片此处描述

在此页面上测试:

hasScrollbar(document.querySelector('.lang-js.s-code-block'), 'vertical')

This function takes an element and a direction (either vertical, horizontal, or both) as arguments and returns true if the element has scroll bars in the specified direction(s), and false otherwise.

function hasScrollbar(el, direction = 'both') {
  const style = window.getComputedStyle(el);
  if (direction === 'vertical' || direction === 'both') {
    if (el.clientHeight < el.scrollHeight || style.overflowY === 'scroll' || style.overflowY === 'auto') {
      return true;
    }
  }

  if (direction === 'horizontal' || direction === 'both') {
    if (el.clientWidth < el.scrollWidth || style.overflowX === 'scroll' || style.overflowX === 'auto') {
      return true;
    }
  }

  return false;
}

enter image description here

Test on this page:

hasScrollbar(document.querySelector('.lang-js.s-code-block'), 'vertical')
你是年少的欢喜 2024-10-22 18:20:22

对于 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,但当存在滚动条时,报告的滚动高度大约比 clientHeight 大 9

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

吹梦到西洲 2024-10-22 18:20:22

对于水平滚动条来说,最有可能的是基于高度的计算,类似于

element.offsetHeight - element.clientHeight

简而言之,对于水平滚动条,根据高度计算检查滚动条,对于垂直滚动条,反之亦然。

Most likely for the horizontal scrollbar, it will be a height based calculation something like this

element.offsetHeight - element.clientHeight?

In a nutshell, for horizontal scrollbars, check the scrollbars based on height calculation, and for vertical scrollbars it's vice versa.

划一舟意中人 2024-10-22 18:20:22

只是在这里乱搞,因为上述解决方案都不适合我(到目前为止)。
我在比较 Div 的滚动高度与其 offsetHeight 方面取得了一些成功,

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

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

Just messing around here as none of the above solutions worked out for me (so far).
I have found some success with comparing a Div's scrollheight against its offsetHeight

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

It seems to give me an acurate comparison...so far. Does someone know if this is legitimate?

多情出卖 2024-10-22 18:20:22

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

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

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

none of this answers are correct. you have to use this :

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

var hasHorizontalScrollbar = (div.offsetWidth > div.clientWidth);
var hasVerticalScrollbar = (div.offsetHeight > div.clientHeight);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文