检查 HTML 元素是不是有滚动条
Posted
技术标签:
【中文标题】检查 HTML 元素是不是有滚动条【英文标题】:Check whether HTML element has scrollbars检查 HTML 元素是否有滚动条 【发布时间】:2011-06-20 07:19:11 【问题描述】:检查元素是否有滚动条最快的方法是什么?
一件事当然是检查元素是否大于其视口,这可以通过检查这两个值来轻松完成:
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 的代码也极大地帮助了我解决问题。它为我指明了正确的方向。
【问题讨论】:
【参考方案1】:在其中添加一个 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];
【讨论】:
如果我已经为此使用了 jQuery,我宁愿只做$(el).css("overflow/overflowX/overflowY")
并查看它是设置为 auto 还是 scroll。 但我想避免使用 jQuery。
CSS 样式不会告诉你元素是否有滚动条。只是它是否可以有滚动条。也许找到一种确定内部元素宽度的跨浏览器方法?
@Soumya92:可滚动大小和实际大小之间的大小比较是微不足道的,我已经在上面写了...我现在需要检查的是特定元素上的当前溢出设置。
@Soumya92:这正是我所需要的。使用 coalesce computedStyle = el.currentStyle || document.defaultView.getComputedStyle(el, null);
也可以大大简化它
还有一件事:这是如何跨浏览器的?这个支持哪些浏览器?【参考方案2】:
试试:
垂直滚动条
el.scrollHeight > el.clientHeight
水平滚动条
el.scrollWidth > el.clientWidth
我知道这至少适用于 IE8 和 Firefox 3.6+。
【讨论】:
我指出是的,这告诉我某个元素比看起来要大,但这并不意味着它会显示滚动条。它也可以有overflow:hidden
并且它不再是可滚动的。
并且使用 clientHeight/clientWidth 值检查并不能给出好的结果,因为元素也可以有边框,这不包括在这个度量中。检查我的公式。它比你的效果更好。
使用 offsetHeight/offsetWidth 代替 clientHeight/clientWidth 检查滚动条是正确的。感谢您指出这一点。
@RobertKoritnik - 所以只需检查该特定元素上是否有overflow:hidden
...在我看来这仍然是正确答案,因为它是最简单的。【参考方案3】:
这可能看起来(或)有点老套,但您可以测试scrollTop
和scrollLeft
属性。
如果它们大于 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
【讨论】:
比较offsetHeight
和clientHeight
会更容易检查滚动条。当滚动条存在时,后者总是比滚动条小。
@Robert:不确定是否更容易,但我确实知道它是如何工作的。然后我假设如果一个元素有overflow:scroll
,无论滚动条是否启用,你都希望它被报告为可滚动的。当然,如果附加了 onscroll 事件,我的解决方案可能会出现问题。
并非如此。如果您检查我的jQuery plugin,我必须找到实际的可滚动祖先,否则我无法将元素滚动到视图中。
@RobertKoritnik 不正确;某些浏览器可能具有不会减小宽度的滚动条。例如在 OS X 上。或触摸设备。
总是返回 false【参考方案4】:
几周前我在某个地方发现了这个。它对我有用。
var div = document.getElementById('container_div_id');
var hasHorizontalScrollbar = div.scrollWidth > div.clientWidth;
var hasVerticalScrollbar = div.scrollHeight > div.clientHeight;
/* you'll get true/false */
【讨论】:
你显然有一个简化的例子。如果您的容器上设置了overflow:hidden
怎么办?会有多余的内容,但它仍然不可滚动。问题远没有看起来那么简单。
这可能不是公认的解决方案,但它对我有用。我不知道如果它被隐藏了你为什么要滚动它。
这可能不是公认的解决方案,但它对我有用。罗伯特,对于这些情况,你不能也获取 css 溢出属性来测试这些情况(例如div.scrollHeight>div.clientHeight && !(div.style.overflow && div.style.overflow == 'hidden')
)吗?
这在很多情况下都会失败。如果您的元素溢出:可见;宽度:200px;并且有一个宽度为 500px 的子元素,您的元素没有滚动条,但 scrollWidth 为 500px,clientWidth 为 200px。
如果溢出可见或隐藏,通常没有滚动条。【参考方案5】:
我参加聚会可能有点晚了,但是...
我相信您可以使用 e.offsetWidth 与 e.clientWidth 检测滚动条。偏移宽度包括边框和滚动条、填充和宽度。客户端宽度包括填充和宽度。请看:
https://developer.mozilla.org/en/DOM/element.offsetWidth(第二张图片) https://developer.mozilla.org/en/DOM/element.clientWidth(第二张图片)
您需要检查:
-
元素是否使用计算/级联/当前样式将溢出设置为自动/滚动(包括溢出X/Y)。
如果元素确实将溢出设置为自动/滚动。建立 offsetWidth 和 clientWidth。
如果 clientWidth 小于 offsetWidth - 右边框(通过计算/级联/当前样式再次找到),那么您知道您有一个滚动条。
对垂直(偏移量/客户端高度)执行相同操作。
IE7 报告某些元素的 clientHeight 为 0(我没有检查原因),因此您总是需要第一次溢出检查。
希望这会有所帮助!
【讨论】:
【参考方案6】:只是在这里搞乱,因为上述解决方案都没有为我解决(到目前为止)。 我发现将 Div 的滚动高度与其 offsetHeight 进行比较取得了一些成功
var oh = $('#wrapDiv').get(0).offsetHeight;
var sh = $('#wrapDiv').get(0).scrollHeight;
这似乎给了我一个准确的比较......到目前为止。有人知道这是否合法吗?
【讨论】:
我想你想要 scrollHeight 和 clientHeight:***.com/questions/4106538/…【参考方案7】:这是另一个解决方案:
正如一些人指出的那样,仅比较 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,
;
【讨论】:
如果overflow*
是scroll
总会有一个滚动条,所以我想你想要vertical: overflowY === 'scroll' || overflowY === 'auto' && node.scrollHeight > node.clientHeight
等等(即去掉括号,所以scroll*
与client*
仅经过测试当overflow*
是auto
)。否则这似乎是最正确的解决方案。
@Jake 如果滚动溢出时 scrollHeight
【参考方案8】:
这些答案都不正确。你必须使用这个:
var div = document.getElementById('container_div_id');
var hasHorizontalScrollbar = (div.offsetWidth > div.clientWidth);
var hasVerticalScrollbar = (div.offsetHeight > div.clientHeight);
【讨论】:
这被否决了,因为它是从 6 年前接受的答案中复制/粘贴的,并且您不需要括号将某些东西变成布尔值。【参考方案9】:对于 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,但在存在滚动条时报告约为 9
【讨论】:
【参考方案10】:在检查滚动条是否存在的情况下存在几个问题,其中之一是在 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;
;
【讨论】:
+10 不是必须的,较低的值也应该起作用。 @sudazzle 问题是某些浏览器的工作方式与缩放相关。 +10 只是一个边距,但如果您不考虑缩放,那么即使使用 +1 或 +2 也可以。【参考方案11】:如果您需要知道整个网页是否存在滚动条并且完整的浏览器支持,您可以使用:
const hasScrollbar = document.body.scrollHeight > window.innerHeight
使用window.innerHeight
而不是document.body.clientHeight
很重要,因为在某些移动浏览器中 clientHeight 不会获得地址栏的大小,但 scrollHeight 会,所以你得到错误的计算。
【讨论】:
以上是关于检查 HTML 元素是不是有滚动条的主要内容,如果未能解决你的问题,请参考以下文章
Selenium WebDriver如何使滚动条滚动到最元素位置
Javascript禁止父元素滚动条滚动, pc移动端均有效