Wie kann man genau feststellen, ob ein Element scrollbar ist?

Lesezeit: 5 Minuten

Benutzer-Avatar
McCroskey

Ich arbeite an einer benutzerdefinierten Knockout-Bindung, die bestimmt, ob ein bestimmtes Element gescrollt wird, und die gebundene Observable mit der Oberseite des Elements relativ zum Ansichtsfenster aktualisiert. Im Moment scheint die Bindung zu funktionieren, aber ich mache mir Sorgen, ob es Umstände gibt, unter denen dies nicht der Fall ist.

HTML:

Scroll position: <span data-bind="text: scrollPosition"></span>

<div class="longdiv">    
    <p data-bind="scroll: scrollPosition">This is some text.</p>
    <div class="shim"></div>
</div>

CSS:

.longdiv {
    width: 200px;
    height: 200px;
    overflow: scroll;
    border: 1px solid black;
}

JS:

ko.bindingHandlers.scroll = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var firstScrollableContainer = null;

        var binding = allBindings.get('scroll');

        $(element).parents().each(function (i, parent) {
            if ($(parent).css('overflow')=='scroll') {
                firstScrollableContainer = parent;
                return false;
            }
        });

        firstScrollableContainer = firstScrollableContainer || window;                

        binding(element.getBoundingClientRect().top);

        $(firstScrollableContainer).scroll(function() {            
            binding(element.getBoundingClientRect().top);
        });
    }
};

var ViewModel = function() {
    var self = this;

    self.scrollPosition = ko.observable(0);
};

ko.applyBindings(new ViewModel());

JSFiddle

Die Bindung nimmt das Element und verwendet jQuery, um die übergeordnete Kette nach oben zu gehen, um zu sehen, ob das übergeordnete Element overflow: scroll set hat. Wenn es ein div mit overflow: scroll findet, bindet es einen Event-Handler an das scroll-Event dieses Elements. Wenn es kein übergeordnetes Element mit overflow: scroll findet, wird es an das scroll-Ereignis des Fensters gebunden.

Also, was ich suche, angesichts eines Dokuments, das so strukturiert ist:

body > div > div > div > p

ist das enthaltende Element, das p am nächsten ist und gescrollt werden kann, sodass ich einen Ereignishandler daran anhängen kann.

Meine Frage ist: Betrachtet man Overflow: Scrollen Sie einen ausreichenden Test, um zu sehen, ob ein übergeordnetes Element gescrollt werden kann? Wenn nein, worauf muss ich achten?

BEARBEITEN: Basierend auf Ihren hilfreichen Kommentaren und Antworten ist hier die Lösung, die ich gefunden habe:

function scrollable(element) {
    var vertically_scrollable, horizontally_scrollable;

    var e = $(element);

     if (   e.css('overflow') == 'scroll' 
         || e.css('overflow') == 'auto'
         || e.css('overflowY') == 'scroll'
         || e.css('overflowY') == 'auto'
         || e.css('height') != 'none'
         || e.css('max-height') != 'none'                          
         ) {
         return true;
    } else {
        return false;
    }
}

  • Ich neige dazu zu denken, dass die Überprüfung overflow, overflow-x und overflow-y sollte reichen, bin mir aber nicht sicher. Überprüfen Sie dies: jsperf.com/jquery-scrollable

    – Alejandro Ivan

    29. April 2015 um 23:38 Uhr


  • Ein Kommentar: Sie können jQuery verwenden scrollTop() um die Bildlaufposition zu erhalten, anstatt getBoundingClientRect falls Sie es wollen.

    – Michael Best

    30. April 2015 um 20:55 Uhr

Benutzer-Avatar
Michael Best

Wollen Sie wissen, ob ein Element jemals scrollen kann oder derzeit scrollen kann?

Kann ein Element jemals scrollen?

Ein Element kann scrollen, wenn es ein Fixed hat height (oder max-height) und overflow-y ist scroll oder auto. Aber da es nicht einfach ist festzustellen, ob die Höhe eines Elements festgelegt ist oder nicht, reicht es wahrscheinlich aus, es einfach zu überprüfen overflow-y:

e.css('overflow-y') == 'scroll' || e.css('overflow-y') == 'auto'

Kann ein Element gerade scrollen?

Ein Element kann jetzt scrollen, wenn es scrollHeight ist größer als sein clientHeight und ob es eine Bildlaufleiste hat, die durch Vergleich bestimmt werden kann clientWidth und offsetWidth (unter Berücksichtigung von Rändern und Rändern) oder prüfen, ob overflow-y ist scroll oder auto.

  • Insbesondere möchte ich wissen, ob es jemals scrollen kann, damit ich ihm einen Event-Handler anhängen kann, wenn dies der Fall ist.

    – McCroskey

    30. April 2015 um 16:19 Uhr

  • Es stellt sich heraus, dass es schwierig ist herauszufinden, ob ein Element eine feste Höhe hat. e.css('height') gibt immer einen Pixelwert zurück.

    – Michael Best

    30. April 2015 um 20:51 Uhr

Benutzer-Avatar
RafaelKr

Dies ist wahrscheinlich die sicherste Lösung (jQuery erforderlich, für einfaches JavaScript siehe unten):

$.fn.isHScrollable = function () {
    return this[0].scrollWidth > this[0].clientWidth;
};

$.fn.isVScrollable = function () {
    return this[0].scrollHeight > this[0].clientHeight;
};

$.fn.isScrollable = function () {
    return this[0].scrollWidth > this[0].clientWidth || this[0].scrollHeight > this[0].clientHeight;
};

Dann können Sie wie folgt prüfen, ob ein Element scrollbar ist:

$(parent).isScrollable();

Für die Verwendung ohne jQuery können Sie Funktionen wie diese implementieren:

function isScrollable(element) {
    return element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight;
};

var myParent = document.getElementById('myParent')
isScrollable(myParent)

  • Diese Lösung kann zurückkehren true für Elemente, die haben overflow:hidden oder overflow:visible → diese Fälle können scrollHeight > clientHeight haben, ohne scrollbar zu sein

    – Philipp

    27. Juni 2021 um 19:39 Uhr

Zusammenführen der beiden Antworten und Hinzufügen von a kleines Etwas Ich selbst verwende dies, um das vertikale Scrollen zu überprüfen. Es kann leicht für andere Fälle umgebaut werden. (H & VH)

function isScrollable(e){
    if( e.scrollTopMax !== undefined )
        return e.scrollTopMax > 0; //All Hail Firefox and it's superior technology!

    if( e == document.scrollingElement ) //If what you're checking is BODY (or HTML depending on your css styles)
        return e.scrollHeight > e.clientHeight; //This is a special case.

    return e.scrollHeight > e.clientHeight && ["scroll", "auto"].indexOf(getComputedStyle(e).overflowY) >= 0



}

Ich habe dies auf Firefox und Chromium getestet. Beide Linux. Vielleicht möchten Sie sie trotzdem selbst überprüfen.

  • Die zusätzliche Prüfung auf Überlauf (x/y) entfällt, da dies bei den vorherigen Prüfungen automatisch ermittelt wird.

    – RafaelKr

    26. August 2019 um 13:37 Uhr

  • Es gibt Elemente, die nicht als scrollbar markiert sind, sie werden einfach aus ihrer übergeordneten Box überflogen und sollen nicht gescrollt werden. Wenn Sie den Teil weglassen, den Sie für den Stil überprüfen, bedeutet dies, dass Sie diese als tatsächlich scrollbar betrachten. Außerdem funktioniert das ScrollTopMax von Firefox nicht so, daher führt das Weglassen auch zu inkonsistentem Verhalten.

    – Aliqandil

    26. August 2019 um 13:47 Uhr

  • Ich bin mir nicht sicher, wie dies auf Mobilgeräten funktionieren würde, auf denen Bildlaufelemente ohne sichtbare Bildlaufleiste vorhanden sind

    – Garr Godfrey

    6. Februar 2021 um 3:12 Uhr

  • Eine sichtbare Bildlaufleiste ist genau das, ein visuelles Element. sollte nichts über den Code bewirken. (Auch Desktop-Browser können ihre Scrollbar ausblenden)

    – Aliqandil

    6. Februar 2021 um 14:03 Uhr

Benutzer-Avatar
Nikos M.

Obwohl dies eine alte Frage ist, werde ich nach verschiedenen fehlgeschlagenen Versuchen, festzustellen, ob ein Element vorhanden ist, meine eigene (neueste) Antwort posten, die korrekt funktioniert eigentlich scrollbar.

function canScroll(el, scrollAxis) {
    if (0 === el[scrollAxis]) {
        el[scrollAxis] = 1;
        if (1 === el[scrollAxis]) {
            el[scrollAxis] = 0;
            return true;
        }
    } else {
        return true;
    }
    return false;
}

function isScrollableX(el) {
    return (el.scrollWidth > el.clientWidth) && canScroll(el, 'scrollLeft') && ('hidden' !== getComputedStyle(el).overflowX);
}

function isScrollableY(el) {
    return (el.scrollHeight > el.clientHeight) && canScroll(el, 'scrollTop') && ('hidden' !== getComputedStyle(el).overflowY);
}

function isScrollable(el) {
    return isScrollableX(el) || isScrollableY(el);
}

Verwenden:

console.log(isScrollable(document.querySelector('#myElement')));

1136660cookie-checkWie kann man genau feststellen, ob ein Element scrollbar ist?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy