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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2146874/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:57:27  来源:igfitidea点击:

Detect if a page has a vertical scrollbar?

javascriptjqueryscroll

提问by Woody

I just want some simple JQ/JS to check if the current page/window (not a particular element) has a vertical scrollbar.

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

Googling gives me stuff that seems overly complex for just this basic feature.

谷歌搜索给我的东西对于这个基本功能来说似乎过于复杂。

How can this be done?

如何才能做到这一点?

回答by Thiago Belem

$(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:<");
    }
});

回答by Andy E

try this:

尝试这个:

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

This will only tell you if the vertical scrollHeight is bigger than the height of the viewable content, however. The hasVScrollvariable will contain true or false.

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

If you need to do a more thorough check, add the following to the code above:

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

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

回答by Bharat

I tried the previous answer and doesn't seem to be working the $("body").height() does not necessarily represent the whole html height.

我尝试了以前的答案,但似乎没有起作用 $("body").height() 不一定代表整个 html 高度。

I have corrected the solution as follows:

我已更正解决方案如下:

// 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:<"); 
} 

回答by hashchange

Let's bring this question back from the dead ;) There is a reason Google doesn't give you a simple solution. Special cases and browser quirks affect the calculation, and it is not as trivial as it seems to be.

让我们把这个问题从死里复活 ;) 谷歌没有给你一个简单的解决方案是有原因的。特殊情况和浏览器怪癖会影响计算,并没有看起来那么简单。

Unfortunately, there are problems with the solutions outlined here so far. I don't mean to disparage them at all - they are great starting points and touch on all the key properties needed for a more robust approach. But I wouldn't recommend copying and pasting the code from any of the other answers because

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

  • they don't capture the effect of positioned content in a way that is reliable cross-browser. The answers which are based on body size miss this entirely (the body is not the offset parent of such content unless it is positioned itself). And those answers checking $( document ).width()and .height()fall prey to jQuery's buggy detection of document size.
  • Relying on window.innerWidth, if the browser supports it, makes your code fail to detect scroll bars in mobile browsers, where the width of the scroll bar is generally 0. They are just shown temporarily as an overlay and don't take up space in the document. Zooming on mobile also becomes a problem that way (long story).
  • The detection can be thrown off when people explicitly set the overflow of both the htmland bodyelement to non-default values (what happens then is a little involved - see this description).
  • In most answers, body padding, borders or margins are not detected and distort the results.
  • 它们不会以可靠的跨浏览器的方式捕捉定位内容的效果。基于正文大小的答案完全忽略了这一点(正文不是此类内容的偏移父级,除非它本身被定位)。而这些答案会检查$( document ).width().height()成为jQuery 对文档大小的错误检测的牺牲品。
  • 依赖window.innerWidth,如果浏览器支持的话,会让你的代码在移动浏览器中检测不到滚动条,滚动条的宽度一般为0。它们只是暂时显示为一个叠加,不占用文档空间. 在移动设备上缩放也成为一个问题(长话短说)。
  • 当人们明确地将htmlbody元素的溢出设置为非默认值时,检测可能会被取消(然后发生的事情有点复杂 - 请参阅此描述)。
  • 在大多数答案中,没有检测到正文填充、边框或边距,并且会扭曲结果。

I have spent more time than I would have imagined on a finding a solution that "just works" (cough). The algorithm I have come up with is now part of a plugin, jQuery.isInView, which exposes a .hasScrollbarmethod. Have a look at the sourceif you wish.

我花了比我想象的更多的时间来寻找“有效”的解决方案(咳嗽)。我提出的算法现在是插件jQuery.isInView 的一部分,它公开了一个.hasScrollbar方法。如果您愿意,请查看

In a scenario where you are in full control of the page and don't have to deal with unknown CSS, using a plugin may be overkill - after all, you know which edge cases apply, and which don't. However, if you need reliable results in an unknown environment, then I don't think the solutions outlined here will be enough. You are better off using a well-tested plugin - mine or anybody elses.

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

回答by Kees C. Bakker

This one did works for me:

这个对我有用:

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

For the body, just use hasVerticalScroll().

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

回答by Roman Zaykovsky

var hasScrollbar = window.innerWidth > document.documentElement.clientWidth;

回答by David Gilbertson

Oddly none of these solutions tell you if a page has a vertical scrollbar.

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

window.innerWidth - document.body.clientWidthwill give you the width of the scrollbar. This should work in anything IE9+ (not tested in the lesser browsers). (Or to strictly answer the question, !!(window.innerWidth - document.body.clientWidth)

window.innerWidth - document.body.clientWidth会给你滚动条的宽度。这应该适用于任何 IE9+(未在较小的浏览器中测试)。(或者严格回答这个问题,!!(window.innerWidth - document.body.clientWidth)

Why? Let's say you have a page where the content is taller than the window height and the user can scroll up/down. If you're using Chrome on a Mac with no mouse plugged in, the user will not see a scrollbar. Plug a mouse in and a scrollbar will appear. (Note this behaviour can be overridden, but that's the default AFAIK).

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

回答by Don D.

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

This one will tell you if you have a scrollbar or not. I've included some information that may help with debugging, which will display as a JavaScript alert.

这个会告诉你是否有滚动条。我已经包含了一些可能有助于调试的信息,这些信息将显示为 JavaScript 警报。

Put this in a script tag, after the closing body tag.

把它放在一个 script 标签中,在结束 body 标签之后。

回答by Sergii Shvager

I found vanila solution

我找到了香草解决方案

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

回答by agm1984

I wrote an updated version of Kees C. Bakker's answer:

我写了 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()
}

The function returns true or false depending whether the page has a vertical scrollbar or not.

该函数根据页面是否具有垂直滚动条返回 true 或 false。

For example:

例如:

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

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