web-dev-qa-db-ja.com

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

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

グーグルは、この基本的な機能だけでは非常に複雑に思えるものを提供してくれます。

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

115
Woody
$(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:<");
    }
});
91
Thiago Belem

これを試して:

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");
71
Andy E

私は前の答えを試しましたが、$( "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:<"); 
} 
41
Bharat

この質問を死から復活させましょう;)Googleがあなたに簡単な解決策を与えない理由があります。特別なケースやブラウザの癖が計算に影響を与えますが、それはそれほど簡単ではありません。

残念ながら、これまでにここで概説したソリューションには問題があります。私はそれらを決して非難するつもりはありません-それらは素晴らしい出発点であり、より堅牢なアプローチに必要なすべての重要な特性に触れます。ただし、他の回答からコードをコピーして貼り付けることはお勧めしません。

  • 配置されたコンテンツの効果を、信頼できるクロスブラウザーの方法でキャプチャしません。ボディサイズに基づいた回答は、これを完全に見逃しています(ボディは、それ自体が配置されない限り、そのようなコンテンツのオフセット親ではありません)。そして、$( document ).width().height()をチェックする回答は、 jQueryのドキュメントサイズのバグ検出 の犠牲になります。
  • ブラウザーがサポートしている場合、window.innerWidthに依存すると、スクロールバーの幅が通常0であるモバイルブラウザーでコードがスクロールバーを検出できなくなります。これらは一時的にオーバーレイとして表示され、ドキュメント内のスペースを増やします。モバイルでのズームもそのように問題になります(長い話)。
  • html要素とbody要素の両方のオーバーフローをデフォルト以外の値に明示的に設定すると、検出が失敗する可能性があります(その後の処理は少し複雑です- この説明 を参照してください) =)。
  • ほとんどの回答では、ボディのパディング、境界線、または余白は検出されず、結果が歪んでいます。

「うまくいく」(咳)解決策を見つけるのに想像以上に多くの時間を費やしました。私が思いついたアルゴリズムは、現在プラグイン jQuery.isInView の一部であり、 a .hasScrollbar method を公開しています。ご覧ください ソースで 必要に応じて。

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

17
hashchange

これは私のために働いた:

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()を使用します。

14
Kees C. Bakker
var hasScrollbar = window.innerWidth > document.documentElement.clientWidth;
11
Roman Zaykovsky

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

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

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

3
    <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タグの後に、スクリプトタグに入れます。

2
Don D.

私はバニラソリューションを見つけました

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)
}
2
Sergey Shvager

私が使う

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

ドキュメントのルート要素(つまり、html要素)の幅をウィンドウの内側部分と単純に比較します。

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

スクロールバーの幅も知る必要がある場合:

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

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
agm1984

他のソリューションが私のプロジェクトの1つで機能しなかったため、オーバーフローCSSプロパティをチェックすることになりました

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

ただし、プロップを変更してスクロールバーが表示されなくなった場合にのみ機能し、コンテンツがウィンドウと等しいか小さい場合は機能しません。

0
jcubic