Rileva se una pagina ha una barra di scorrimento verticale?


121

Voglio solo qualche semplice JQ / JS per verificare se la pagina / finestra corrente (non un particolare elemento) ha una barra di scorrimento verticale.

Google mi dà cose che sembrano eccessivamente complesse solo per questa funzionalità di base.

Come si può fare?

Risposte:


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 ma per ragioni di esattezza, questo controlla solo se il contenuto si espande oltre la visualizzazione. Se la overflowproprietà di bodyè impostata su hiddenda qualche parte lungo la linea, non funzionerà. L'impostazione nascosta su un corpo è estremamente rara, però.
Pekka,

4
Questo non funziona se l'altezza del corpo corrisponde all'altezza della finestra, che è il caso se l'altezza del documento corrisponde esattamente al viewport, viene aggiunta una barra di scorrimento orizzontale . Forzerà vert. barra di scorrimento ma l'altezza di doc / body / window è la stessa; NON avviserà la "barra di scorrimento verticale" anche se ce n'è una.
Smettila di calunniare Monica Cellio

2
Ho solo pensato di menzionare che dovevo usare $(document)invece di $("body"), questo ha funzionato per me quando il corpo no (ho un contenitore posizionato in modo assoluto con un rapporto di aspetto su larghezza / altezza)
am_

1
Ho una pagina di report sul browser Chrome in cui inizialmente visualizza una barra di scorrimento e svanisce in pochi millisecondi, il che sembra un comportamento del browser poiché non l'ho programmato. Quindi questa funzione restituisce sempre true nel mio caso ..
Dush

@TiuTalk for me $ ("body"). Height () & $ (window) .height () dà lo stesso valore, invece io uso $ (document) .height ()> $ (window) .height () per cui funziona me.
SarangK

77

prova questo:

var hasVScroll = document.body.scrollHeight > document.body.clientHeight;

Tuttavia, questo ti dirà solo se lo scrollHeight verticale è maggiore dell'altezza del contenuto visualizzabile. La hasVScrollvariabile conterrà vero o falso.

Se è necessario eseguire un controllo più approfondito, aggiungere quanto segue al codice sopra:

// 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
+1 Bello! E con lo stile di calcolo necessario (che era il punto in cui ho deciso di non essere coinvolto in questa domanda;)
Pekka

lol yeah stavo discutendo se fare o meno lo sforzo in più per scriverlo perché in molti casi non è necessario.
Andy E

1
Ciò si traduce in hasVScroll vero ogni volta che overflowY è "visibile" indipendentemente dal fatto che scrollHeight sia maggiore di clientHeight. Forse intendevi cStyle.overflow === 'scroll'?
BT

5
Il codice sopra non funziona. Browser: Chrome 56. Url: news.greylock.com/…
Sebastien Lorber

1
@BT cStyle.overflow == "visible" può mostrare barre di scorrimento quando l'elemento è il file document.body. Ma dovrebbe essere (hasVScroll && cStyle.overflow == "visible" && element.nodeName == "BODY"). Inoltre deve controllare cStyle.overflow === 'scroll'come fai notare.
mseifert

44

Ho provato la risposta precedente e non sembra funzionare su $ ("body"). Height () non rappresenta necessariamente l'intera altezza html.

Ho corretto la soluzione come segue:

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

Riportiamo questa domanda dalla morte;) C'è una ragione per cui Google non ti offre una soluzione semplice. Casi speciali e stranezze del browser influenzano il calcolo e non è così banale come sembra.

Sfortunatamente, ci sono problemi con le soluzioni qui delineate finora. Non intendo affatto screditarli: sono ottimi punti di partenza e toccano tutte le proprietà chiave necessarie per un approccio più solido. Ma non consiglierei di copiare e incollare il codice da nessuna delle altre risposte perché

  • non catturano l'effetto del contenuto posizionato in modo affidabile per tutti i browser. Le risposte basate sulla dimensione del corpo mancano completamente di questo (il corpo non è il genitore offset di tale contenuto a meno che non sia posizionato da solo). E quelle risposte controllano $( document ).width()e .height()cadono preda del rilevamento bug di jQuery delle dimensioni del documento .
  • Fare affidamento su window.innerWidth, se il browser lo supporta, impedisce al codice di rilevare le barre di scorrimento nei browser mobili, dove la larghezza della barra di scorrimento è generalmente 0. Vengono mostrate temporaneamente come una sovrapposizione e non occupano spazio nel documento . Anche lo zoom sui dispositivi mobili diventa un problema in questo modo (storia lunga).
  • Il rilevamento puòessere annullato quando le persone impostano esplicitamente l'overflow di entrambi gli elementi htmle bodysu valori non predefiniti (cosa succede alloraèun po 'complicato - vedi questa descrizione ).
  • Nella maggior parte delle risposte, il riempimento del corpo, i bordi oi margini non vengono rilevati e distorcono i risultati.

Ho speso più tempo di quanto avrei immaginato per trovare una soluzione che "funziona" (tosse). L'algoritmo che ho escogitato fa ora parte di un plugin, jQuery.isInView , che espone un .hasScrollbarmetodo . Dai un'occhiata alla fonte se lo desideri.

In uno scenario in cui hai il pieno controllo della pagina e non devi avere a che fare con CSS sconosciuti, l'utilizzo di un plug-in potrebbe essere eccessivo, dopotutto sai quali casi limite si applicano e quali no. Tuttavia, se hai bisogno di risultati affidabili in un ambiente sconosciuto, non credo che le soluzioni descritte qui saranno sufficienti. È meglio usare un plugin ben collaudato, il mio o chiunque altro.


Grazie. Abbastanza complicato! Se non vuoi / hai bisogno di essere retrocompatibile, esiste forse una soluzione più semplice per i browser html5? Voglio dire, forse i programmatori del browser / w3c sono stati abbastanza carini da dirci se ci sono barre di scorrimento o meno su un elemento? ;-)
Leone

1
@ Leo Non che io sappia. Beh, c'è un window.scrollbarsoggetto che ha una singola proprietà, visible. Sembra promettente ma non lo è. Non è supportato in IE, incluso IE11. E ti dice solo che c'è una barra di scorrimento, ma non quale. Vedi la pagina di prova qui .
cambio hash

Grazie @hashchange. Sembra incredibilmente stupido che dice solo se c'è una barra di scorrimento, quindi immagino che sia solo una sorta di test. Un po 'promettente però. ;-)
Leone

1
@BT Ok, fantastico. Ora lascia che ti conduca all'ingresso della tana del coniglio;) Ecco una demo in cui il contenuto non è sufficiente per riempire la finestra. Il tuo rilevamento funziona in FF ma non riesce in Chrome. Ed ecco un'altra demo in cui un elemento posizionato è posizionato in fondo alla pagina. Il tuo rilevamento funziona in Chrome ma non riesce in FF.
cambio hash il

1
@BT E immagino che possiamo entrare in una serie di strane modalità di errore quando iniziamo a giocare con le impostazioni di overflow perché il loro comportamento è un po 'strano , ma mi sono fermato lì.
cambio hash

15

Questo ha funzionato per me:

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

Per il corpo, basta usare hasVerticalScroll().


Questa è l'unica risposta in questo thread che funziona sul mio Chrome
Nertan Lucian

clientHeightè preferibile offsetHeightqui. Altrimenti puoi avere un bordo spesso e tornare non c'è barra di scorrimento quando c'è.
theicfire


3

Stranamente nessuna di queste soluzioni ti dice se una pagina ha una barra di scorrimento verticale.

window.innerWidth - document.body.clientWidthti darà la larghezza della barra di scorrimento. Questo dovrebbe funzionare in qualsiasi cosa IE9 + (non testato nei browser minori). (O per rispondere rigorosamente alla domanda,!!(window.innerWidth - document.body.clientWidth)

Perché? Supponiamo che tu abbia una pagina in cui il contenuto è più alto dell'altezza della finestra e l'utente può scorrere su / giù. Se stai utilizzando Chrome su un Mac senza mouse collegato, l'utente non vedrà una barra di scorrimento. Collega un mouse e apparirà una barra di scorrimento. (Nota questo comportamento può essere sovrascritto, ma questa è l'impostazione predefinita AFAIK).


La spiegazione del comportamento del Chrome-Mouse mi ha aiutato a capire quello che pensavo fosse un comportamento incoerente. Grazie!
sabato

2

Ho trovato la soluzione Vanila

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
Non funziona in IE 11. window.innerWidth e document.documentElement.clientWidth sono sempre gli stessi.
NLV

Aggiustato. Questa stessa funzione funziona anche per IE 11. Il problema era questo :
stackoverflow.com/questions/17045132/…

L'ho provato in Chrome 65 e funziona. Ma quando lo adeguo per le barre di scorrimento orizzontali, il risultato è strano: se vengono visualizzate sia la barra di scorrimento orizzontale che quella verticale, window.innerWidth > document.documentElement.clientWidthè vero, ma window.innerHeight > document.documentElement.clientHeightnon lo è. Sembra che in questo caso sia stato il contrario. Non sono uno sviluppatore JS, ne ho bisogno solo per i test Selenium. Sono grato per i suggerimenti.
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>

Questo ti dirà se hai una barra di scorrimento o meno. Ho incluso alcune informazioni che potrebbero aiutare con il debug, che verranno visualizzate come un avviso JavaScript.

Inseriscilo in un tag script, dopo il tag body di chiusura.


1

Ho scritto una versione aggiornata della risposta di 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()
}

La funzione restituisce vero o falso a seconda che la pagina abbia o meno una barra di scorrimento verticale.

Per esempio:

const hasVScroll = hasVerticalScroll(document.querySelector('body'))

if (hasVScroll) {
  console.log('HAS SCROLL', hasVScroll)
}

1

Io uso

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

1

Confronta semplicemente la larghezza dell'elemento radice del documento (ovvero l'elemento html) con la parte interna della finestra:

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

Se devi conoscere anche la larghezza della barra di scorrimento:

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

0

Altre soluzioni non hanno funzionato in uno dei miei progetti e ho finito per controllare la proprietà CSS di overflow

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

ma funzionerà solo se la barra di scorrimento appare scomparsa cambiando l'elica, non funzionerà se il contenuto è uguale o inferiore alla finestra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.