ページに垂直スクロールバーがあるかどうかを検出しますか?


121

単純なJQ / JSで、現在のページ/ウィンドウ(特定の要素ではない)に垂直スクロールバーがあるかどうかを確認したいだけです。

グーグルを使用すると、この基本的な機能だけでは複雑すぎるように見えることがあります。

これはどのように行うことができますか?

回答:


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ません。しかし、体に隠される設定は非常にまれです。
ペッカ

4
本体の高さがウィンドウの高さと一致する場合、これは機能しません。これは、ドキュメントの高さがビューポートと正確に一致する場合、水平スクロールバーが追加されます。それは頂点を強制します。スクロールバーですが、doc / body / windowの高さは同じです。「垂直スクロールバー」がある場合でも警告しません。
Sonicaを止めるモニカチェリオ

2
$(document)代わりにを使用する必要があると言っただけですが$("body")、これはボディが機能しないときに機能しました(幅/高さのアスペクト比を持つ絶対位置のコンテナがあります)
am_

1
Chromeブラウザーのレポートページがあり、最初にスクロールバーが表示され、数ミリ秒で消えます。プログラムしていないため、ブラウザーの動作のように見えます。だから、私の場合は常にtrueこの関数の戻り...
Dush

@TiuTalk for me $( "body")。height()&$(window).height()は同じ値を返しますが、代わりに$(document).height()> $(window).height()を使用します私。
SarangK 2016年

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
いいね!そして、必要な計算されたスタイル(これは私がこの質問に関与しないことに決めたポイントでした;)
Pekka

笑ええ、私は多くの場合それが必要とされないので、それを書くために余分な努力をするかどうかについて議論していました。
アンディE

1
これにより、scrollHeightがclientHeightより大きいかどうかに関係なく、overflowYが「可視」の場合は常にhasVScrollがtrueになります。もしかしてcStyle.overflow === 'scroll'
BT

5
上記のコードは機能しません。ブラウザ:クローム56 URL:news.greylock.com/...
セバスチャン・ローバー

1
cStyle.overflow == "visible" 要素がの場合、@ BT はスクロールバーを表示できdocument.bodyます。ただし、(hasVScroll && cStyle.overflow == "visible" && element.nodeName == "BODY")である必要があります。さらにcStyle.overflow === 'scroll'、あなたが指摘するようにそれをチェックする必要があります。
mseifert 2017

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です。これらは一時的にオーバーレイとして表示されるだけで、ドキュメント内のスペースを占有しません。 。モバイルでのズームもそのように問題になります(長い話)。
  • htmlbody要素の両方のオーバーフローをデフォルト以外の値に明示的に設定すると、検出がスローされます(その場合の動作は少し複雑です- この説明を参照してください)。
  • ほとんどの回答では、ボディパディング、境界線、またはマージンは検出されず、結果を歪めます。

「うまくいく」(咳)解決策を見つけるために、想像以上に多くの時間を費やしました。私が思いついたアルゴリズムは現在メソッドを公​​開するプラグインjQuery.isInViewの一部です。.hasScrollbar。顔をしているソースであなたが望むなら。

ページを完全に制御していて、不明なCSSを処理する必要がないシナリオでは、プラグインを使用するのはやり過ぎかもしれません。ただし、未知の環境で信頼できる結果が必要な場合は、ここで概説されているソリューションでは十分ではないと思います。十分にテストされたプラグインを使用するほうがよいです-私または他の誰か。


ありがとう。かなり複雑です!下位互換性を維持したくない場合は、おそらくHTML5ブラウザーの簡単な解決策はありますか?おそらく、ブラウザーのcoders / w3cは、要素にスクロールバーがあるかどうかを教えてくれるだけで十分なのでしょうか?;-)
レオ

1
@Leo私が知っていることではありません。さて、単一のプロパティを持つwindow.scrollbarsオブジェクトがありますvisible。有望に聞こえますが、そうではありません。IE11を含むIEではサポートされていません。そしてそれは単にスクロールバーがあることを告げるだけです-しかし、どのスクロールバーはありません。こちらのテストページをご覧ください
hashchange 2015

@hashchangeに感謝します。スクロールバーがあるかどうかだけを伝えるのは信じられないほど愚かに聞こえるので、それはまだある種のテストにすぎないと思います。少し有望ですが。;-)
レオ、

1
@BTわかりました。ここで、ウサギの穴の入り口に案内します;)これは、コンテンツがウィンドウを埋めるのに十分でないデモです。検出はFFで機能しますが、Chromeでは失敗します。そしてここに、配置された要素がページのはるか下に配置される別のデモがあります。検出はChromeでは機能しますが、FFでは失敗します。
2016年

1
@BTそして、オーバーフロー設定で遊んだら、奇妙な障害モードに入る可能性があると思います。その動作は少し変わっているからですが、ここで停止しました。
hashchange

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


これは私のスレッドで動作するこのスレッドの唯一の回答です
Nertan Lucian

clientHeightoffsetHeightここよりも好ましい。それ以外の場合は、太い境界線を設定し、スクロールバーがない場合はスクロールバーを返すことができます。
theicfire


3

奇妙なことに、これらのソリューションはいずれも、ページに垂直スクロールバーがあるかどうかを教えてくれません。

window.innerWidth - document.body.clientWidthスクロールバーの幅を与えます。これはすべてのIE9 +で動作するはずです(これよりも小さなブラウザーではテストされていません)。(または質問に厳密に答えるために、!!(window.innerWidth - document.body.clientWidth)

どうして?たとえば、コンテンツがウィンドウの高さよりも高く、ユーザーが上下にスクロールできるページがあるとします。マウスが接続されていないMacでChromeを使用している場合、ユーザーにはスクロールバーが表示されません。マウスを接続すると、スクロールバーが表示されます。(この動作はオーバーライドできますが、これはデフォルトのAFAIKです)。


Chrome-Mouseの動作の説明は、一貫性のない動作だと思ったことを理解するのに役立ちました。ありがとう!
theisof 2017

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

修正しました。これと同じ機能が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アラートとして表示されるデバッグに役立つ可能性のあるいくつかの情報を含めました。

これを、body終了タグの後のスクリプトタグに挿入します。


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

他のソリューションが私のプロジェクトの1つで機能せず、オーバーフローのcssプロパティをチェックしてしまう

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

ただし、小道具を変更してスクロールバーが消えたように見える場合にのみ機能します。コンテンツがウィンドウ以下の場合は機能しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.