Come posso verificare se una barra di scorrimento è visibile?

È ansible controllare l’ overflow:auto di un div?

Per esempio:

HTML

 
* content

jquery

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

A volte il contenuto è breve (nessuna barra di scorrimento) e talvolta lungo (barra di scorrimento visibile).

un piccolo plugin per questo.

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

usalo così,

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

testato lavorando su Firefox, Chrome, IE6,7,8

ma non funziona correttamente sul selettore di tag del body

dimostrazione


modificare

Ho scoperto che quando hai una barra di scorrimento orizzontale che fa apparire la barra di scorrimento verticale, questa funzione non funziona …

Ho scoperto un’altra soluzione … uso clientHeight

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

Forse una soluzione più semplice.

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

Dovrei cambiare un po ‘di ciò che Reigel ha detto:

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

innerHeight conta l’altezza del controllo e le sue imbottiture superiore e inferiore

Puoi farlo usando una combinazione degli attributi Element.scrollHeight e Element.clientHeight .

Secondo MDN:

L’ attributo di sola lettura Element.scrollHeight è una misura dell’altezza del contenuto di un elemento, incluso il contenuto non visibile sullo schermo a causa dell’overflow. Il valore scrollHeight è uguale al minimo clientHeight richiesto dall’elemento per adattare tutto il contenuto nel punto di vista senza utilizzare una barra di scorrimento verticale. Include il riempimento degli elementi ma non il suo margine.

E:

La proprietà di sola lettura Element.clientHeight restituisce l’altezza interna di un elemento in pixel, incluso il riempimento ma non l’altezza, il bordo o il margine della barra di scorrimento orizzontale.

clientHeight può essere calcolato come altezza CSS + riempimento CSS – altezza della barra di scorrimento orizzontale (se presente).

Pertanto, l’elemento mostrerà una barra di scorrimento se l’altezza di scorrimento è maggiore dell’altezza del client, quindi la risposta alla tua domanda è:

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

Questo amplia la risposta di @ Reigel. Restituirà una risposta per barre di scorrimento orizzontali o verticali.

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

Esempio:

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

Hai bisogno di element.scrollHeight . Confrontalo con $(element).height() .

Ho creato una nuova custom: pseudo selettore per jQuery per verificare se un elemento ha una delle seguenti proprietà CSS:

  1. overflow: [scorrimento | auto]
  2. overflow-x: [scorrimento | auto]
  3. overflow-y: [scorrimento | auto]

Volevo trovare il genitore scorrevole più vicino di un altro elemento, così ho anche scritto un altro piccolo plugin jQuery per trovare il genitore più vicino con overflow.

Probabilmente questa soluzione non ha le prestazioni migliori, ma sembra funzionare. L’ho usato insieme al plugin $ .scrollTo. A volte ho bisogno di sapere se un elemento si trova all’interno di un altro contenitore scorrevole. In tal caso, desidero scorrere l’elemento scorrevole portatile rispetto alla finestra.

Probabilmente avrei dovuto racchiuderlo in un singolo plugin e aggiunto il selettore psuedo come parte del plugin, oltre a esporre un metodo ‘più vicino’ per trovare il contenitore scorrevole (padre) più vicino.

Qualunque cosa … eccolo qui.

$ .isStrollabile plugin 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’) pseudo selettore jQuery:

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

$ .scrollableparent () Plugin jQuery:

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

L’implementazione è piuttosto semplice

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

AGGIORNAMENTO: Ho scoperto che Robert Koritnik aveva già uno pseudo-selettore molto più potente: scrollabile che identificherà gli assi scorrevoli e l’altezza dei contenitori scorrevoli, come parte del suo plugin jQuery $ .scrollintoview (). plugin scrollintoview

Ecco il suo pseudo selettore di fantasia (oggetti di scena):

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

La prima soluzione di cui sopra funziona solo in IE La seconda soluzione sopra funziona solo in FF

Questa combinazione di entrambe le funzioni funziona in entrambi i browser:

 //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"); }​ 
  • Avvolgere in un documento pronto
  • monitorWidth1: il div in cui l’overflow è impostato su auto
  • mtc: un contenitore div all’interno di monitorWidth1
  • AdjustOverflowWidth: una class css applicata al div #mtc quando la barra di scorrimento è triggers * Utilizzare l’avviso per testare il cross browser e quindi commentare per il codice di produzione finale.

HTH

(scrollWidth / Height – clientWidth / Height) è un buon indicatore per la presenza di una barra di scorrimento, ma in molte occasioni ti darà una risposta “falso positivo”. se è necessario essere precisi, suggerirei di utilizzare la seguente funzione. invece di cercare di indovinare se l’elemento è scorrevole, puoi scorrerlo …

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

Tutte le risposte di tutti qui sono incomplete, e smettiamo di usare jquery nelle risposte SO già per favore. Controlla la documentazione di jquery se vuoi informazioni su jquery.

Ecco una funzione puramente javascript generalizzata per verificare se un elemento ha barre di scorrimento in modo completo:

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

Le soluzioni fornite sopra funzioneranno nella maggior parte dei casi, ma il controllo di scrollHeight e overflow a volte non è sufficiente e non riesce per gli elementi body e html: https://codepen.io/anon/pen/EvzXZw

Questa soluzione controlla se l’elemento è scorrevole:

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

Nota: anche gli elementi con overflow = hidden sono trattati come scrollabili ( maggiori informazioni ), quindi potresti aggiungere una condizione anche in questo caso, se necessario:

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

Spiegazione: Il trucco sta nel fatto che il tentativo di scorrere verso il basso e di ripristinarlo non verrà eseguito dal browser. La funzione più in alto può anche essere scritta come la seguente:

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

Ecco il mio miglioramento: aggiunto parseInt. per qualche strana ragione non ha funzionato senza di essa.

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

Ecco una versione migliorata della risposta di Evan che sembra rappresentare correttamente la logica di overflow.

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

Funziona su Chrome , Edge , Firefox e Opera , almeno nelle versioni più recenti.

Utilizzando JQuery …

Imposta questa funzione per correggere il piè di pagina:

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

Restituisce una funzione. Fatto in questo modo solo per impostare il corpo e il piè di pagina una volta.

E poi, imposta questo quando il documento è pronto.

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

Aggiungi questo al tuo css footer:

 footer { bottom: 0; } 

La maggior parte delle risposte presentate mi ha avvicinato a dove dovevo essere, ma non proprio lì.

Fondamentalmente volevamo valutare se le barre di scorrimento dovessero essere visibili in una situazione normale, con quella definizione che indica che la dimensione dell’elemento del corpo è maggiore della porta di visualizzazione. Questa non era una soluzione presentata, ed è per questo che la sto presentando.

Spero che aiuti qualcuno!

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

Essenzialmente, abbiamo la funzione hasScrollbar , ma restituiamo se l’elemento richiesto è più grande della porta di visualizzazione. Per visualizzare le dimensioni della porta, abbiamo appena usato $(window).height() . Un rapido confronto di ciò con la dimensione dell’elemento, produce i risultati corretti e il comportamento desiderabile.

Trova un genitore dell’elemento corrente con scorrimento verticale o corpo.

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

Può essere utilizzato per eseguire lo scorrimento automatico sull’elemento corrente tramite:

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

Mi dilungherò ancora di più su quelle povere anime che, come me, usano uno dei moderni framework js e non JQuery e sono stati completamente abbandonati dalla gente di questo thread:

questo è stato scritto in Angular 6 ma se scrivi React 16, Vue 2, Polymer, Ionic, React-Native, saprai cosa fare per adattarlo. Ed è l’intero componente quindi dovrebbe essere facile.

 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(){ const th = this; 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(th.scrollAmount.scrollHeight > th.scrollAmount.offsetHeight){ // there is a scroll bar, do something! }else{ // there is NO scroll bar, do something! } }); } } 

nell’html ci sarebbe un div con la class “elem-list” che è stilizzata nel css o scss per avere height e un valore di overflow che non è hidden . (così auto o sroll )

Attivo questa valutazione su un evento di scorrimento perché il mio objective finale era di avere “rotazioni di messa a fuoco automatica” che decidono se stanno scorrendo l’intero set di componenti orizzontalmente se tali componenti non hanno scorrimento verticale disponibile e altrimenti scorrono solo all’interno di uno dei componenti componenti verticalmente.

ma puoi mettere la valutazione altrove per farla innescare da qualcos’altro.

la cosa importante da ricordare qui è che non sei mai forzato a usare JQuery, c’è sempre un modo per accedere alle stesse funzionalità che ha senza usarlo.