スクロールバーが表示されているかどうかを確認するにはどうすればよいですか?


277

overflow:autodivのをチェックすることは可能ですか?

例えば:

HTML

<div id="my_div" style="width: 100px; height:100px; overflow:auto;" class="my_class"> 
  * content
</div>

JQUERY

$('.my_class').live('hover', function (event)
{
    if (event.type == 'mouseenter')
    {
         if( ...  if scrollbar visible ? ... )
         {
            alert('true'):
         }
         else
         {
            alert('false'):
         }
    }

});

コンテンツは短い(スクロールバーがない)場合もあれば、長い(スクロールバーが表示される)場合もあります。

回答:


376

それのための小さなプラグイン。

(function($) {
    $.fn.hasScrollBar = function() {
        return this.get(0).scrollHeight > this.height();
    }
})(jQuery);

このように使います

$('#my_div1').hasScrollBar(); // returns true if there's a `vertical` scrollbar, false otherwise..

Firefox、Chrome、IE6、7、8で動作することをテスト済み

bodyタグセレクターでは正しく機能しない

デモ


編集する

水平スクロールバーが原因で垂直スクロールバーが表示されると、この機能が動作しないことがわかりました。

私は別の解決策を見つけました...使用 clientHeight

return this.get(0).scrollHeight > this.get(0).clientHeight;

22
パディングがある場合は、> this.innerHeight(); jsfiddle.net
p3FFL / 210

2
これには問題があり、水平スクロールバーも存在する場合、垂直スクロールバーが水平スクロールバーの高さによって縮小されるまで存在しても、これはfalseを返します。
アリー

なぜ同じ関数を2回定義したのですか?@jcubic
Nitin Sawant 2013

8
Macでは、スクロールバーはコンテンツ上に浮かんでおり、使用しないと消えます。Windowsでは常に表示され、水平方向のスペースを占有します。そのため、コンテンツをスクロールできる(この関数が検出できる)からといって、必ずしもスクロールバーが存在するわけではありません。
Andrew

2
(function($){$ .fn.hasScrollBar = function(){return this.get(0).scrollWidth> this.width); }})(jQuery); これは、水平オーバーフォローで機能します。iframe内のWebサイトでモバイルの応答性を確認するのに適しています。
アレクサンドルニコラスポパ

56

多分もっと簡単な解決策です。

if ($(document).height() > $(window).height()) {
    // scrollbar
}

この回答は、JQuery.ready()
Simple Sandman '29

4
これは、スクロールバーがウィンドウ上にあり、div要素ではないことを前提としています。参照を変更して提案する:「メインウィンドウでスクロールバーをテストするだけの場合は、次の方法を試してみてください。」
justdan23

43

これは、Element.scrollHeightおよびElement.clientHeight属性の組み合わせを使用して行うことができます。

MDNによると:

Element.scrollHeight読み取り専用属性が原因オーバーフローに画面に表示されないコンテンツを含む要素の内容の高さの測定値です。scrollHeightの値は、垂直スクロールバーを使用せずにビューポイントのすべてのコンテンツを収めるために要素が必要とする最小のclientHeightに等しくなります。要素のパディングは含まれますが、マージンは含まれません。

そして:

Element.clientHeightは、読み取り専用プロパティは、パディングはなく、水平スクロールバーの高さ、境界、またはマージンを含むピクセル要素の内側の高さを返します。

clientHeightは、CSSの高さ+ CSSのパディング-水平スクロールバーの高さ(存在する場合)として計算できます。

したがって、スクロールの高さがクライアントの高さより大きい場合、要素はスクロールバーを表示するので、質問に対する答えは次のとおりです。

function scrollbarVisible(element) {
  return element.scrollHeight > element.clientHeight;
}

2
例:github.com/twbs/bootstrap/blob/master/js/modal.js#L242およびMDNの見積もりと説明については+1!
lowtechsun 2015

scrollHeightに含まれていないよりもコンテンツに境界線がある場合、クロームで
AT

1
フレームワークやライブラリを使用していないことに賛成票を投じました。
John

注意-これはリフローを引き起こしますが、これはパフォーマンスの低下です。gist.github.com/paulirish/5d52fb081b3570c81e3a
トッドショーランダー

43

レイゲルの言ったことを少し変更する必要があります。

(function($) {
    $.fn.hasScrollBar = function() {
        return this[0] ? this[0].scrollHeight > this.innerHeight() : false;
    }
})(jQuery);

innerHeightは、コントロールの高さとその上部および下部のパディングをカウントします


return(this.get(0))?this.get(0).scrollHeight> this.innerHeight():false;
commonpike 2012年

3
これが正解だと思います。これはFF35、IE11、Chrome39で動作しました。
LucasBr 2015

scrollHeight条件が満たされたときにスクロールバーが表示されるように 'overflow'値をチェックしません。
BT

1
@BTしかし、CSSでオーバーフローが自動に設定されている場合、この追加のチェックは必要ありませんか?サイズを比較してそれで十分...?
Andrew

あなたのためだけに働く答えは答えではありません。他の人々が彼らのCSSに持っているものをどのように知るのですか?あなたの答えはその制限に言及していません。誰かがあなたの答えをドロップしてそれを機能させることができない場合、それは良い答えではありません。
BT

27

これは@Reigelの答えを拡張したものです。水平または垂直スクロールバーの回答を返します。

(function($) {
    $.fn.hasScrollBar = function() {
        var e = this.get(0);
        return {
            vertical: e.scrollHeight > e.clientHeight,
            horizontal: e.scrollWidth > e.clientWidth
        };
    }
})(jQuery);

例:

element.hasScrollBar()             // Returns { vertical: true/false, horizontal: true/false }
element.hasScrollBar().vertical    // Returns true/false
element.hasScrollBar().horizontal  // Returns true/false


8

アイテムに次のcssプロパティのいずれかがあるかどうかをテストするために、jQueryの新しいカスタム:pseudoセレクターを作成しました。

  1. オーバーフロー:[スクロール|自動]
  2. オーバーフロー-x:[スクロール|自動]
  3. オーバーフロー-y:[スクロール|自動]

別の要素の最も近いスクロール可能な親を見つけたかったので、オーバーフローで最も近い親を見つけるための別の小さなjQueryプラグインも作成しました。

このソリューションはおそらく最高のパフォーマンスを発揮しませんが、機能しているようです。$ .scrollToプラグインと組み合わせて使用​​しました。要素が別のスクロール可能なコンテナ内にあるかどうかを知る必要がある場合があります。その場合、親のスクロール可能な要素とウィンドウをスクロールします。

おそらくこれを単一のプラグインにラップし、プラグインの一部として疑似セレクターを追加し、最も近い(親)スクロール可能なコンテナーを見つけるための「最も近い」メソッドを公開する必要があったでしょう。

Anywho ....こちらです。

$ .isScrollable jQueryプラグイン:

$.fn.isScrollable = function(){
    var elem = $(this);
    return (
    elem.css('overflow') == 'scroll'
        || elem.css('overflow') == 'auto'
        || elem.css('overflow-x') == 'scroll'
        || elem.css('overflow-x') == 'auto'
        || elem.css('overflow-y') == 'scroll'
        || elem.css('overflow-y') == 'auto'
    );
};

$( ':scrollable')jQuery擬似セレクター:

$.expr[":"].scrollable = function(a) {
    var elem = $(a);
    return elem.isScrollable();
};

$ .scrollableparent()jQueryプラグイン:

$.fn.scrollableparent = function(){
    return $(this).closest(':scrollable') || $(window); //default to $('html') instead?
};

実装は非常に簡単です

//does a specific element have overflow scroll?
var somedivIsScrollable = $(this).isScrollable();
//use :scrollable psuedo selector to find a collection of child scrollable elements
var scrollableChildren = $(this).find(':scrollable');
//use $.scrollableparent to find closest scrollable container
var scrollableparent = $(this).scrollableparent();

更新:私は、Robert Koritnikがすでに$ .scrollintoview()jQueryプラグインの一部として、スクロール可能な軸とスクロール可能なコンテナーの高さを識別する、より強力な:scrollable疑似セレクターを考案したことを発見しました。scrollintoviewプラグイン

ここに彼の派手な疑似セレクター(小道具)があります:

    $.extend($.expr[":"], {

    scrollable: function (element, index, meta, stack) {

        var direction = converter[typeof (meta[3]) === "string" && meta[3].toLowerCase()] || converter.both;

        var styles = (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(element, null) : element.currentStyle);

        var overflow = {

            x: scrollValue[styles.overflowX.toLowerCase()] || false,

            y: scrollValue[styles.overflowY.toLowerCase()] || false,

            isRoot: rootrx.test(element.nodeName)

        };



        // check if completely unscrollable (exclude HTML element because it's special)

        if (!overflow.x && !overflow.y && !overflow.isRoot)

        {

            return false;

        }



        var size = {

            height: {

                scroll: element.scrollHeight,

                client: element.clientHeight

            },

            width: {

                scroll: element.scrollWidth,

                client: element.clientWidth

            },

            // check overflow.x/y because iPad (and possibly other tablets) don't dislay scrollbars

            scrollableX: function () {

                return (overflow.x || overflow.isRoot) && this.width.scroll > this.width.client;

            },

            scrollableY: function () {

                return (overflow.y || overflow.isRoot) && this.height.scroll > this.height.client;

            }

        };

        return direction.y && size.scrollableY() || direction.x && size.scrollableX();

    }

});

6

上記の最初のソリューションはIEでのみ機能します上記の2番目のソリューションはFFでのみ機能します

両方の機能のこの組み合わせは、両方のブラウザーで機能します。

//Firefox Only!!
if ($(document).height() > $(window).height()) {
    // has scrollbar
    $("#mtc").addClass("AdjustOverflowWidth");
    alert('scrollbar present - Firefox');
} else {
    $("#mtc").removeClass("AdjustOverflowWidth");
}

//Internet Explorer Only!!
(function($) {
    $.fn.hasScrollBar = function() {
        return this.get(0).scrollHeight > this.innerHeight();
    }
})(jQuery);
if ($('#monitorWidth1').hasScrollBar()) {
    // has scrollbar
    $("#mtc").addClass("AdjustOverflowWidth");
    alert('scrollbar present - Internet Exploder');
} else {
    $("#mtc").removeClass("AdjustOverflowWidth");
}​
  • 準備ができたドキュメントでラップ
  • monitorWidth1:オーバーフローが自動に設定されているdiv
  • mtc:monitorWidth1内のコンテナーdiv
  • AdjustOverflowWidth:スクロールバーがアクティブなときに#mtc divに適用されるcssクラス*アラートを使用してクロスブラウザーをテストし、最終的な製品コードをコメント化します。

HTH


6

(scrollWidth / Height-clientWidth / Height)は、スクロールバーの存在を示す良い指標ですが、多くの場合、「誤検知」の回答を示します。正確である必要がある場合は、次の関数を使用することをお勧めします。要素がスクロール可能かどうかを推測する代わりに、スクロールすることができます...

function isScrollable( el ){
  var y1 = el.scrollTop;
  el.scrollTop  += 1;
  var y2 = el.scrollTop;
  el.scrollTop  -= 1;
  var y3 = el.scrollTop;
  el.scrollTop   = y1;
  var x1 = el.scrollLeft;
  el.scrollLeft += 1;
  var x2 = el.scrollLeft;
  el.scrollLeft -= 1;
  var x3 = el.scrollLeft;
  el.scrollLeft  = x1;
  return {
    horizontallyScrollable: x1 !== x2 || x2 !== x3,
    verticallyScrollable: y1 !== y2 || y2 !== y3
  }
}
function check( id ){
  alert( JSON.stringify( isScrollable( document.getElementById( id ))));
}
#outer1, #outer2, #outer3 {
  background-color: pink;
  overflow: auto;
  float: left;
}
#inner {
  width:  150px;
  height: 150px;
}
button {  margin: 2em 0 0 1em; }
<div id="outer1" style="width: 100px; height: 100px;">
  <div id="inner">
    <button onclick="check('outer1')">check if<br>scrollable</button>
  </div>
</div>
<div id="outer2" style="width: 200px; height: 100px;">
  <div id="inner">
    <button onclick="check('outer2')">check if<br>scrollable</button>
  </div>
</div>
<div id="outer3" style="width: 100px; height: 180px;">
  <div id="inner">
    <button onclick="check('outer3')">check if<br>scrollable</button>
  </div>
</div>


どのような場合に誤検知が発生しますか?
GaloisGirl

5

ここのみんなの答えは不完全ですが、SOの答えでjqueryを使うのをやめてください。jqueryに関する情報が必要な場合は、jqueryのドキュメントを確認してください。

要素に完全な方法でスクロールバーがあるかどうかをテストするための一般化された純粋なJavaScript関数を次に示します。

// dimension - Either 'y' or 'x'
// computedStyles - (Optional) Pass in the domNodes computed styles if you already have it (since I hear its somewhat expensive)
function hasScrollBars(domNode, dimension, computedStyles) {
    dimension = dimension.toUpperCase()
    if(dimension === 'Y') {
        var length = 'Height'
    } else {
        var length = 'Width'
    }

    var scrollLength = 'scroll'+length
    var clientLength = 'client'+length
    var overflowDimension = 'overflow'+dimension

    var hasVScroll = domNode[scrollLength] > domNode[clientLength]


    // Check the overflow and overflowY properties for "auto" and "visible" values
    var cStyle = computedStyles || getComputedStyle(domNode)
    return hasVScroll && (cStyle[overflowDimension] == "visible"
                         || cStyle[overflowDimension] == "auto"
                         )
          || cStyle[overflowDimension] == "scroll"
}

4
jqueryとしてフラグが付けられた質問でjqueryを使用しないのはなぜですか?言及しているjqueryドキュメントの部分へのリンクを追加してください。
kpull1

6
@ kpull1あまりにも多くの人々が、彼らが持っているすべての1つのjavascript質問でjQueryにタグを付けます。この質問はjQueryとの関係がありません。ありません jQueryのこれをしないので、答えを持っているjQueryのドキュメントのどの部分も、またそれする必要があります。
BT

4

私のように、JQueryではなく最新の jsフレームワークの1つを使用し、このスレッドの人々によって完全に放棄された貧しい人々のために、これをさらに拡張します。

これはAngular 6で書かれていますが、React 16、Vue 2、Polymer、Ionic、React-Nativeと書けば、それを適応させるために何をすべきかわかるでしょう。そしてそれは全体のコンポーネントなので、それは簡単なはずです。

import {ElementRef, AfterViewInit} from '@angular/core';

@Component({
  selector: 'app',
  templateUrl: './app.html',
  styleUrls: ['./app.scss']
})
export class App implements AfterViewInit {
scrollAmount;

constructor(
  private fb: FormBuilder,
  private element: ElementRef 
) {}

ngAfterViewInit(){
  this.scrollAmount = this.element.nativeElement.querySelector('.elem-list');
  this.scrollAmount.addEventListener('wheel', e => { //you can put () instead of e
  // but e is usefull if you require the deltaY amount.
    if(this.scrollAmount.scrollHeight > this.scrollAmount.offsetHeight){
       // there is a scroll bar, do something!
    }else{
       // there is NO scroll bar, do something!
    }
  });
}
}

HTMLには、「elem-list」クラスのdivがあり、cssまたはscssでスタイル設定されて、a heightoverflowない値を持ちhiddenます。(そうautosroll

スクロールイベントでこのevalをトリガーするのは、私の最終目標が「自動フォーカススクロール」であり、コンポーネントに垂直スクロールがない場合にコンポーネントのセット全体を水平にスクロールするかどうかを決定することでした。それ以外の場合は、1つの内部のみをスクロールします。垂直方向のコンポーネント。

ただし、evalを別の場所に配置して、別の何かによってトリガーされるようにすることができます。

ここで覚えておくべき重要なことは、JQueryを強制的に使用することは決してないということです。JQueryを使用せずに、同じ機能に常にアクセスする方法があります。


1
ホイールイベントをリッスンして、スクロールバーがあるかどうかを確認する理由を知りたいと思います。
mix3d 2018年

3
また、矢印関数を使用しthisているため、親スコープを保持します。th = this;不要です。
mix3d 2018年

1
mix3d I個人的に動的である所定の尖った要素にスクロール方向を有し、自動的にそれに基づいて、水平および垂直スクロールを切り替えるためにこのコードを使用@
タツ

1
Re:これ; これは基本的には構文糖(プラスいい略記)ですfunction(){}.bind(this)
mix3d

1

これは、オーバーフローロジックを適切に説明しているように見える、エヴァンの回答の改良版です。

            function element_scrollbars(node) {
                var element = $(node);
                var overflow_x = element.css("overflow-x");
                var overflow_y = element.css("overflow-y");
                var overflow = element.css("overflow");
                if (overflow_x == "undefined") overflow_x == "";
                if (overflow_y == "undefined") overflow_y == "";
                if (overflow == "undefined") overflow == "";
                if (overflow_x == "") overflow_x = overflow;
                if (overflow_y == "") overflow_y = overflow;
                var scrollbar_vertical = (
                    (overflow_y == "scroll")
                    || (
                        (
                            (overflow_y == "hidden")
                            || (overflow_y == "visible")
                        )
                        && (
                            (node.scrollHeight > node.clientHeight)
                        )
                    )
                );
                var scrollbar_horizontal = (
                    (overflow_x == "scroll")
                    || (
                        (
                            (overflow_x == "hidden")
                            || (overflow_x == "visible")
                        )
                        && (
                            (node.scrollWidth > node.clientWidth)
                        )
                    )
                );
                return {
                    vertical: scrollbar_vertical,
                    horizontal: scrollbar_horizontal
                };
            }

1

上記の解決策はほとんどの場合に機能しますが、scrollHeightとオーバーフローをチェックするだけでは不十分な場合があり、次のようにbody要素とhtml要素で失敗する可能性があります。https://codepen.io/anon/pen/EvzXZw

1.解決策-要素がスクロール可能かどうかを確認します。

function isScrollableY (element) {
  return !!(element.scrollTop || (++element.scrollTop && element.scrollTop--));
}

注:を含む要素overflow: hiddenもスクロール可能(詳細)として扱われるため、必要に応じてそれに対する条件を追加することもできます。

function isScrollableY (element) {
    let style = window.getComputedStyle(element);
    return !!(element.scrollTop || (++element.scrollTop && element.scrollTop--)) 
           && style["overflow"] !== "hidden" && style["overflow-y"] !== "hidden";
}

私が知る限り、このメソッドは要素にがある場合にのみ失敗しますscroll-behavior: smooth

説明:トリックは、下にスクロールして元に戻す試みがブラウザによってレンダリングされないことです。最上位の関数は、次のように書くこともできます。

2.解決策-必要なチェックをすべて行います。

function isScrollableY (element) {
  const style = window.getComputedStyle(element);

  if (element.scrollHeight > element.clientHeight &&
      style["overflow"] !== "hidden" && style["overflow-y"] !== "hidden" &&
      style["overflow"] !== "clip" && style["overflow-y"] !== "clip"
  ) {
    if (element === document.documentElement) return true;
    else if (style["overflow"] !== "visible" && style["overflow-y"] !== "visible") {
      // special check for body element (https://drafts.csswg.org/cssom-view/#potentially-scrollable)
      if (element === document.body) {
        const parentStyle = window.getComputedStyle(element.parentElement);
        if (parentStyle["overflow"] !== "visible" && parentStyle["overflow-y"] !== "visible" &&
            parentStyle["overflow"] !== "clip" && parentStyle["overflow-y"] !== "clip"
        ) {
          return true;
        }
      }
      else return true;
    }
  }

  return false;
}

0

これが私の改善です:parseIntを追加しました。いくつかの奇妙な理由で、それなしでは機能しませんでした。

// usage: jQuery('#my_div1').hasVerticalScrollBar();
// Credit: http://stackoverflow.com/questions/4814398/how-can-i-check-if-a-scrollbar-is-visible
(function($) {
    $.fn.hasVerticalScrollBar = function() {
        return this.get(0) ? parseInt( this.get(0).scrollHeight ) > parseInt( this.innerHeight() ) : false;
    };
})(jQuery);

0

上の作品クロムエッジFirefoxのオペラ少なくとも新しいバージョンでは、。

jQueryを使用しています...

この関数を設定してフッターを修正します。

function fixFooterCaller()
{
    const body = $('body');
    const footer = $('body footer');

    return function ()
    {
        // If the scroll bar is visible
        if ($(document).height() > $(window).height())
        {
            // Reset
            footer.css('position', 'inherit');
            // Erase the padding added in the above code
            body.css('padding-bottom', '0');
        }
        // If the scrollbar is NOT visible
        else
        {
            // Make it fixed at the bottom
            footer.css('position', 'fixed');
            // And put a padding to the body as the size of the footer
            // This makes the footer do not cover the content and when
            // it does, this event fix it
            body.css('padding-bottom', footer.outerHeight());
        }
    }
}

関数を返します。この方法で作成したのは、ボディとフッターを1回だけ設定するためです。

そして、ドキュメントの準備ができたらこれを設定します。

$(document).ready(function ()
{
    const fixFooter = fixFooterCaller();

    // Put in a timeout call instead of just call the fixFooter function
    // to prevent the page elements needed don't be ready at this time
    setTimeout(fixFooter, 0);
    // The function must be called every time the window is resized
    $(window).resize(fixFooter);
});

これをフッターのCSSに追加してください:

footer {
    bottom: 0;
}

0

提示された答えのほとんどは、私が必要な場所に近づきましたが、そこまでは行きませんでした。

基本的に、通常の状況でスクロールバーが表示されるかどうかを評価する必要がありました。その定義では、body要素のサイズがビューポートより大きいことを意味します。これは提示された解決策ではなかったので、私はそれを提出しています。

うまくいけば、それは誰かを助けるでしょう!

(function($) {
    $.fn.hasScrollBar = function() {
        return this.get(0).scrollHeight > $(window).height();
    }
})(jQuery);

基本的にはhasScrollbar関数がありますが、要求された要素がビューポートより大きい場合は戻ります。ビューポートのサイズには、を使用しました$(window).height()。要素のサイズと比較すると、正しい結果と望ましい動作が得られます。


0

垂直スクロールまたは本体を持つ現在の要素の親を見つけます。

$.fn.scrollableParent = function() {
    var $parents = this.parents();

    var $scrollable = $parents.filter(function(idx) {
        return this.scrollHeight > this.offsetHeight && this.offsetWidth !== this.clientWidth;
    }).first();

    if ($scrollable.length === 0) {
        $scrollable = $('html, body');
    }
    return $scrollable;
};

次の方法で現在の要素に自動スクロールするために使用できます。

var $scrollable = $elem.scrollableParent();
$scrollable.scrollTop($elem.position().top);

0

フレームワークなしのJavaScriptアプローチ、垂直と水平の両方をチェックします

 /*
 * hasScrollBars
 * 
 * Checks to see if an element has scrollbars
 * 
 * @returns {object}
 */
Element.prototype.hasScrollBars = function() {
    return {"vertical": this.scrollHeight > this.style.height, "horizontal": this.scrollWidth > this.style.width};
}

このように使います

if(document.getElementsByTagName("body")[0].hasScrollBars().vertical){
            alert("vertical");
}

        if(document.getElementsByTagName("body")[0].hasScrollBars().horizontal){
            alert("horizontal");
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.