检测页面是否具有垂直滚动条?


121

我只希望一些简单的JQ / JS检查当前页面/窗口(不是特定元素)是否具有垂直滚动条。

谷歌搜索为我提供的东西对于此基本功能似乎过于复杂。

如何才能做到这一点?

Answers:


97
$(document).ready(function() {
    // Check if body height is higher than window height :)
    if ($("body").height() > $(window).height()) {
        alert("Vertical Scrollbar! D:");
    }

    // Check if body width is higher than window width :)
    if ($("body").width() > $(window).width()) {
        alert("Horizontal Scrollbar! D:<");
    }
});

14
+1,但是为了精确起见,这仅检查内容是否比视口扩展得更大。如果将的overflow属性body设置为hidden沿线的某处,则它将无效。但是,隐藏在身体上的设置极为罕见。
Pekka 2010年

4
如果主体高度与窗口高度匹配,则此方法不起作用,如果文档高度与视口完全匹配,则添加了水平滚动条。它将强制垂直。滚动条,但文档/正文/窗口高度相同;即使有一个,它也不会警告“垂直滚动条”。
停止诽谤Monica Cellio 2012年

2
只是以为我要提到必须使用$(document)代替$("body"),这对于我的身体没有作用(我有一个绝对正位置的容器,纵横比在宽度/高度上)对我
有用

1
我在Chrome浏览器上有一个报告页面,该页面最初显示滚动条并在几毫秒内消失,这看起来像浏览器的行为,因为我没有对其进行编程。所以,这个函数返回后在我的情况真的永远..
Dush

@TiuTalk对我来说$(“ body”)。height()&$(window).height()给出相同的值,相反,我使用$(document).height()> $(window).height()我。
SarangK

77

试试这个:

var hasVScroll = document.body.scrollHeight > document.body.clientHeight;

但是,这只会告诉您垂直的scrollHeight是否大于可见内容的高度。该hasVScroll变量将包含true或false。

如果需要进行更彻底的检查,请在上面的代码中添加以下内容:

// Get the computed style of the body element
var cStyle = document.body.currentStyle||window.getComputedStyle(document.body, "");

// Check the overflow and overflowY properties for "auto" and "visible" values
hasVScroll = cStyle.overflow == "visible" 
             || cStyle.overflowY == "visible"
             || (hasVScroll && cStyle.overflow == "auto")
             || (hasVScroll && cStyle.overflowY == "auto");

1
+1好!并采用了必要的计算样式(这是我决定不参与此问题的关键点;)
Pekka 2010年

大声笑是的,我正在辩论是否要付出额外的努力来编写它,因为在很多情况下它是不需要的。
安迪E

1
无论何时scrollHeight是否大于clientHeight,这都会导致hasVScroll在true时“ Y”可见时为true。也许是你的意思cStyle.overflow === 'scroll'
英国电信

5
上面的代码不起作用。浏览器:Chrome浏览器56.地址:news.greylock.com/...
塞巴斯蒂安·洛伯

1
cStyle.overflow == "visible" 当元素为时,@ BT 可以显示滚动条document.body。但这应该是(hasVScroll && cStyle.overflow ==“ visible” && element.nodeName ==“ BODY”)。另外,cStyle.overflow === 'scroll'如您所指出的,还需要检查。
mseifert

44

我尝试了前面的答案,但似乎无法使用$(“ body”)。height()不一定代表整个html高度。

我已更正解决方案,如下所示:

// Check if body height is higher than window height :) 
if ($(document).height() > $(window).height()) { 
    alert("Vertical Scrollbar! D:"); 
} 

// Check if body width is higher than window width :) 
if ($(document).width() > $(window).width()) { 
    alert("Horizontal Scrollbar! D:<"); 
} 

18

让我们把这个问题从死灰复燃中带回来;)Google不能为您提供简单的解决方案是有原因的。特殊情况和浏览器怪异会影响计算,但它似乎并不那么琐碎。

不幸的是,到目前为止,这里概述的解决方案存在问题。我并不是要完全贬低它们-它们是一个很好的起点,并且触及了更强大方法所需的所有关键属性。但是我不建议从其他任何答案中复制和粘贴代码,因为

  • 它们无法以可靠的跨浏览器方式捕获定位内容的影响。基于主体大小的答案完全会错过这一点(除非主体本身定位,否则主体不是此类内容的偏移父对象)。那些答案检查$( document ).width().height()成为jQuery对文档大小的错误检测的牺牲品。
  • 依靠 window.innerWidth如果浏览器支持,则它,使您的代码无法在移动浏览器中检测到滚动条,滚动条的宽度通常为0。它们只是临时显示为覆盖图,不会占用文档中的空间。从长远来看,缩放手机也成为一个问题。
  • 当人们明确将htmland body元素的溢出都设置为非默认值时,检测可能会被取消(随后会发生什么事,请稍作干预-请参阅此说明)),。
  • 在大多数答案中,未检测到正文填充,边框或边距,并使结果失真。

我花了比我想像的更多的时间来寻找一个“行之有效”的解决方案(咳嗽)。我想出的算法现在是jQuery.isInView插件的一部分,该插件公开.hasScrollbarmethod。如果需要,请查看

在您完全控制页面并且不必处理未知CSS的情况下,使用插件可能会过大-毕竟,您知道哪些情况适用,哪些情况不适用。但是,如果您需要在未知环境中获得可靠的结果,那么我认为这里概述的解决方案是不够的。您最好使用经过良好测试的插件-我的或其他任何人。


谢谢。有点复杂!如果您不希望/不需要向后兼容,那么是否有针对HTML5浏览器的更简单解决方案?我的意思是也许浏览器编码器/ w3c足够好,可以告诉我们元素上是否有滚动条?;-)
Leo

1
@Leo我不知道。好吧,有一个具有单个属性的window.scrollbars对象visible。听起来很有希望,但事实并非如此。IE(包括IE11)不支持它。它只是告诉您有一个滚动条-但没有滚动条。请参阅此处测试页
hashchange

谢谢@hashchange。听起来很愚蠢,它只是告诉您是否有任何滚动条,所以我想这只是某种测试。虽然有点前途。;-)
Leo

1
@BT好的,太好了。现在,让我带您到兔子洞的入口;)这是一个演示,其中内容不足以填满窗口。您的检测在FF中有效,但在Chrome中失败。这是另一个演示,其中将定位的元素放置在页面的下方。您的检测在Chrome中有效,但在FF中失败。
hashchange '16

1
@BT我想当我们开始使用溢出设置时,我们会陷入一堆奇怪的失败模式,因为它们的行为有点奇怪,但我已经停在那儿了。
hashchange '16

15

这确实为我工作:

function hasVerticalScroll(node){
    if(node == undefined){
        if(window.innerHeight){
            return document.body.offsetHeight> window.innerHeight;
        }
        else {
            return  document.documentElement.scrollHeight > 
                document.documentElement.offsetHeight ||
                document.body.scrollHeight>document.body.offsetHeight;
        }
    }
    else {
        return node.scrollHeight> node.offsetHeight;
    }
}

对于身体,只需使用hasVerticalScroll()


这是在我的Chrome上运行的该线程中唯一的答案
Nertan Lucian

clientHeightoffsetHeight这里更可取。否则,您可以使用粗边框,如果有则返回没有滚动条。
theicfire


3

奇怪的是,这些解决方案都不能告诉您页面是否具有垂直滚动条。

window.innerWidth - document.body.clientWidth将为您提供滚动条的宽度。这可以在任何IE9 +中使用(未在较小的浏览器中测试)。(或严格回答问题,!!(window.innerWidth - document.body.clientWidth)

为什么?假设您有一个页面,其中内容比窗口高度高,并且用户可以向上/向下滚动。如果您在Mac上使用Chrome且未插入鼠标,则用户将不会看到滚动条。插入鼠标,将出现一个滚动条。(请注意,此行为可以被覆盖,但这是默认的AFAIK)。


Chrome鼠标行为的解释帮助我弄清了我认为不一致的行为。谢谢!
theisof

2

我找到了香草溶液

var hasScrollbar = function() {
  // The Modern solution
  if (typeof window.innerWidth === 'number')
    return window.innerWidth > document.documentElement.clientWidth

  // rootElem for quirksmode
  var rootElem = document.documentElement || document.body

  // Check overflow style property on body for fauxscrollbars
  var overflowStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowStyle = rootElem.currentStyle.overflow

  overflowStyle = overflowStyle || window.getComputedStyle(rootElem, '').overflow

    // Also need to check the Y axis overflow
  var overflowYStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowYStyle = rootElem.currentStyle.overflowY

  overflowYStyle = overflowYStyle || window.getComputedStyle(rootElem, '').overflowY

  var contentOverflows = rootElem.scrollHeight > rootElem.clientHeight
  var overflowShown    = /^(visible|auto)$/.test(overflowStyle) || /^(visible|auto)$/.test(overflowYStyle)
  var alwaysShowScroll = overflowStyle === 'scroll' || overflowYStyle === 'scroll'

  return (contentOverflows && overflowShown) || (alwaysShowScroll)
}


1
在IE 11中不起作用。window.innerWidth和document.documentElement.clientWidth始终相同。
NLV

解决它。此功能也适用于IE 11。问题是这样的- stackoverflow.com/questions/17045132/...
NLV

我在Chrome 65中对此进行了测试,并且可以正常工作。但是,当我将其调整为水平滚动条时,结果很奇怪:如果同时显示水平和垂直滚动条,window.innerWidth > document.documentElement.clientWidth则为true,但window.innerHeight > document.documentElement.clientHeight不是。在这种情况下,看起来好像是相反的方式。我不是JS开发人员,我只需要Selenium测试即可。我很感谢提示。
kriegaex

2
    <script>
    var scrollHeight = document.body.scrollHeight;
    var clientHeight = document.documentElement.clientHeight;
    var hasVerticalScrollbar = scrollHeight > clientHeight;

    alert(scrollHeight + " and " + clientHeight); //for checking / debugging.
    alert("hasVerticalScrollbar is " + hasVerticalScrollbar + "."); //for checking / debugging.
    </script>

这将告诉您是否有滚动条。我提供了一些可能有助于调试的信息,这些信息将显示为JavaScript警报。

将其放在结束标签后的script标签中。


1

我写了Kees C. Bakker答案的更新版本:

const hasVerticalScroll = (node) => {
  if (!node) {
    if (window.innerHeight) {
      return document.body.offsetHeight > window.innerHeight
    }
    return (document.documentElement.scrollHeight > document.documentElement.offsetHeight)
      || (document.body.scrollHeight > document.body.offsetHeight)
  }
  return node.scrollHeight > node.offsetHeight
}

if (hasVerticalScroll(document.querySelector('body'))) {
  this.props.handleDisableDownScrollerButton()
}

该函数返回true或false,这取决于页面是否具有垂直滚动条。

例如:

const hasVScroll = hasVerticalScroll(document.querySelector('body'))

if (hasVScroll) {
  console.log('HAS SCROLL', hasVScroll)
}

1

我用

public windowHasScroll()
{
    return document.body.clientHeight > document.documentElement.clientHeight;
}

1

只需将文档根元素(即html元素)的宽度与窗口的内部部分进行比较:

if ((window.innerWidth - document.documentElement.clientWidth) >0) console.log('V-scrollbar active')

如果还需要知道滚动条的宽度:

vScrollbarWidth = window.innerWidth - document.documentElement.clientWidth;

0

其他解决方案在我的一个项目中不起作用,并且我最终检查了溢出的CSS属性

function haveScrollbar() {
    var style = window.getComputedStyle(document.body);
    return style["overflow-y"] != "hidden";
}

但仅当滚动条通过更改道具消失而消失时,它才起作用;如果内容等于或小于窗口,则它将不起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.