it-swarm.com.de

Wie kann ich überprüfen, ob eine Bildlaufleiste sichtbar ist?

Ist es möglich, die overflow:auto eines div?

Zum Beispiel:

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

});

Manchmal ist der Inhalt kurz (keine Bildlaufleiste) und manchmal lang (Bildlaufleiste sichtbar).

257
Peter

ein kleines Plugin dafür.

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

benutze es so,

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

getestet mit Firefox, Chrome, IE6, 7, 8

funktioniert jedoch in der Tag-Auswahl von body nicht ordnungsgemäß

Demo


Bearbeiten

Ich habe herausgefunden, dass diese Funktion nicht funktioniert, wenn Sie eine horizontale Bildlaufleiste haben, die eine vertikale Bildlaufleiste anzeigt.

Ich habe eine andere Lösung gefunden ... benutze clientHeight

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

Vielleicht eine einfachere Lösung.

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

Ich sollte etwas an dem ändern, was Reigel gesagt hat:

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

innerHeight zählt die Höhe des Steuerelements und seine oberen und unteren Polsterungen

40
kpull1

Sie können dies mit einer Kombination aus Element.scrollHeight und Element.clientHeight Attribute.

Laut MDN:

Das schreibgeschützte Attribut Element.scrollHeight ​​gibt die Höhe des Inhalts eines Elements an, einschließlich des Inhalts, der aufgrund eines Überlaufs nicht auf dem Bildschirm angezeigt wird. Der scrollHeight-Wert entspricht der minimalen clientHeight, die das Element benötigen würde, um den gesamten Inhalt des Ansichtspunkts ohne Verwendung einer vertikalen Bildlaufleiste anzupassen. Das Element wird aufgefüllt, der Rand jedoch nicht.

Und:

Die schreibgeschützte Eigenschaft Element.clientHeight ​​gibt die innere Höhe eines Elements in Pixel zurück, einschließlich des Auffüllens, jedoch nicht der Höhe, des Rahmens oder des Rands der horizontalen Bildlaufleiste.

clientHeight kann berechnet werden als CSS-Höhe + CSS-Abstand - Höhe der horizontalen Bildlaufleiste (falls vorhanden).

Daher zeigt das Element eine Bildlaufleiste an, wenn die Bildlaufhöhe größer als die Clienthöhe ist. Die Antwort auf Ihre Frage lautet daher:

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

Dies erweitert die Antwort von @ Reigel. Es wird eine Antwort für horizontale oder vertikale Bildlaufleisten zurückgegeben.

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

Beispiel:

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

Sie benötigen element.scrollHeight . Vergleichen Sie es mit $(element).height().

12
Boldewyn

Ich habe einen neuen benutzerdefinierten Pseudo-Selektor für jQuery erstellt, um zu testen, ob ein Element eine der folgenden CSS-Eigenschaften aufweist:

  1. überlauf: [scroll | auto]
  2. overflow-x: [scroll | auto]
  3. überlauf-y: [scroll | auto]

Ich wollte das nächstgelegene scrollbare Elternelement eines anderen Elements finden, also habe ich auch ein weiteres kleines jQuery-Plugin geschrieben, um das nächstgelegene Elternelement mit Überlauf zu finden.

Diese Lösung bietet wahrscheinlich nicht die beste Leistung, scheint jedoch zu funktionieren. Ich habe es in Verbindung mit dem $ .scrollTo-Plugin verwendet. Manchmal muss ich wissen, ob sich ein Element in einem anderen scrollbaren Container befindet. In diesem Fall möchte ich das übergeordnete scrollbare Element mit dem Fenster vergleichen.

Ich hätte dies wahrscheinlich in einem einzigen Plugin zusammenfassen und den Pseudo-Selektor als Teil des Plugins hinzufügen sowie eine Methode "next" bereitstellen müssen, um den nächstgelegenen (übergeordneten) scrollbaren Container zu finden.

Egal ... hier ist es.

$. isScrollable jQuery-Plugin:

$.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-Pseudoselektor:

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

$. scrollableparent () jQuery-Plugin:

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

Die Implementierung ist ziemlich einfach

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

UPDATE: Ich fand, dass Robert Koritnik bereits einen viel mächtigeren: scrollbaren Pseudo-Selektor entwickelt hat, der die scrollbaren Achsen und die Höhe scrollbarer Container wie ein Teil seines jQuery-Plugins $ .scrollintoview (). scrollintoview plugin

Hier ist sein ausgefallener Pseudo-Selektor (Requisiten):

    $.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();

    }

});
7

Die obige erste Lösung funktioniert nur in IE Die obige zweite Lösung funktioniert nur in FF

Diese Kombination beider Funktionen funktioniert in beiden Browsern:

//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");
}​
  • Wickeln Sie ein Dokument fertig ein
  • monitorWidth1: das div, bei dem der Überlauf auf auto gesetzt ist
  • mtc: ein container div in monitorWidth1
  • AdjustOverflowWidth: Eine CSS-Klasse, die auf das Div #mtc angewendet wird, wenn die Bildlaufleiste aktiv ist.

HTH

6
Aaron Hopkins

(scrollWidth/Height - clientWidth/Height) ist ein guter Indikator für das Vorhandensein einer Bildlaufleiste, gibt Ihnen jedoch bei vielen Gelegenheiten eine "falsch positive" Antwort. wenn Sie genau sein müssen, würde ich vorschlagen, die folgende Funktion zu verwenden. Anstatt zu erraten, ob das Element scrollbar ist, können Sie einen Bildlauf durchführen ...

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>
6
Yair Levy

Die Antworten von allen hier sind unvollständig, und wir können die Verwendung von jquery in SO answers already please einstellen. Überprüfen Sie die Dokumentation von jquery, wenn Sie Informationen zu jquery wünschen.

Hier ist eine verallgemeinerte Pure-Javascript-Funktion, mit der Sie testen können, ob ein Element vollständig über Bildlaufleisten verfügt:

// 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
B T

Die oben aufgeführten Lösungen funktionieren in den meisten Fällen, aber die Überprüfung von scrollHeight und overflow reicht manchmal nicht aus und schlägt für body- und html-Elemente fehl: https://codepen.io/anon/pen/EvzXZw

Diese Lösung prüft, ob das Element scrollbar ist:

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

Hinweis: Elemente mit overflow = hidden werden ebenfalls als scrollbar behandelt ( more info ), daher können Sie eine Bedingung dagegen hinzufügen bei Bedarf auch:

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

Erklärung: Der Trick ist, dass der Versuch, nach unten zu scrollen und es zurückzusetzen, nicht vom Browser gerendert wird. Die oberste Funktion kann auch folgendermaßen geschrieben werden:

function isScrollableY (element) {
  // if scrollTop is not 0 / larger than 0, then the element is scrolled and therefore must be scrollable
  // -> true  
  if (element.scrollTop === 0) {
    // if the element is zero it may be scrollable  
    // -> try scrolling about 1 pixel
    element.scrollTop++;
    // if the element is zero then scrolling did not succeed and therefore it is not scrollable 
    // -> false  
    if (element.scrollTop === 0) return false;
    // else the element is scrollable; reset the scrollTop property
    // -> true
    element.scrollTop--;
  }
  return true;
}
2
Robbendebiene

Ich werde dies noch weiter ausdehnen für jene armen Seelen, die, wie ich, eines der modernen j-Frameworks und nicht JQuery verwenden und von den Menschen in ganz aufgegeben wurden dieser Thread:

dies wurde in Angular 6 geschrieben, aber wenn Sie React 16, Vue 2, Polymer, Ionic, React-Native Sie werden wissen, was zu tun ist, um es anzupassen. Und es ist die gesamte Komponente, so dass es einfach sein sollte.

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

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

in html gäbe es ein div mit der klasse "elem-list", das in css oder scss so formatiert ist, dass es einen height und einen overflow Wert hat, der nicht hidden ist ]. (also auto oder sroll)

Ich löse diese Auswertung bei einem Bildlaufereignis aus, weil mein Endziel darin bestand, "automatische Fokus-Bildläufe" zu haben, die entscheiden, ob der gesamte Komponentensatz horizontal gescrollt wird, wenn für diese Komponenten kein vertikaler Bildlauf verfügbar ist, und ansonsten nur die Innereien eines der Komponenten gescrollt werden Komponenten vertikal.

sie können die Auswertung jedoch an einer anderen Stelle platzieren, damit sie von etwas anderem ausgelöst wird.

wichtig hierbei ist, dass Sie niemals gezwungen sind , JQuery wieder zu verwenden. Es gibt immer eine Möglichkeit, auf dieselben Funktionen zuzugreifen, die es hat, ohne sie zu verwenden.

2
tatsu

Hier ist eine verbesserte Version von Evans Antwort, die die Überlauflogik zu berücksichtigen scheint.

            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
JBlitzen

Die meisten der vorgestellten Antworten brachten mich an den Punkt, an dem ich sein musste, aber nicht ganz dort.

Grundsätzlich wollten wir beurteilen, ob die Bildlaufleisten in einer normalen Situation sichtbar sind, dh, die Größe des Hauptteils ist größer als das Ansichtsfenster. Dies war keine vorgestellte Lösung, weshalb ich sie vorlege.

Hoffentlich hilft es jemandem!

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

Grundsätzlich haben wir die Funktion hasScrollbar, geben aber zurück, wenn das angeforderte Element größer als der View-Port ist. Für die Größe des View-Ports haben wir nur $(window).height() verwendet. Ein schneller Vergleich mit der Elementgröße liefert die richtigen Ergebnisse und das gewünschte Verhalten.

0
Barry Chapman

Suchen Sie ein übergeordnetes Element des aktuellen Elements mit vertikalem Bildlauf oder Körper.

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

Es kann verwendet werden, um automatisch zum aktuellen Element zu scrollen:

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

Funktioniert auf Chrome, Edge, Firefox und Opera, zumindest in den neueren Versionen.

JQuery verwenden ...

Richten Sie diese Funktion ein, um die Fußzeile zu korrigieren:

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

Es gibt eine Funktion zurück. Gemacht auf diese Weise, nur um den Körper und die Fußzeile einmal zu setzen.

Stellen Sie dies dann ein, wenn das Dokument fertig ist.

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

Fügen Sie dies zu Ihrer Fußzeile hinzu:

footer {
    bottom: 0;
}
0
Mateus Pires

Hier ist meine Verbesserung: ParseInt hinzugefügt. Aus irgendeinem seltsamen Grund funktionierte es ohne sie nicht.

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