Как я могу проверить, видна ли полоса прокрутки? - PullRequest
255 голосов
/ 27 января 2011

Можно ли проверить overflow:auto div?

Например:

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

});

Иногда содержимое короткое (без полосы прокрутки), а иногда длинное (видимая полоса прокрутки).

Ответы [ 17 ]

2 голосов
/ 07 сентября 2017

Решения, представленные выше, будут работать в большинстве случаев, но проверка scrollHeight и переполнения иногда недостаточна и не работает для элементов body и html: https://codepen.io/anon/pen/EvzXZw

Это решение проверяет, является ли элементпрокручиваемый:

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

Примечание: элементы с переполнением = скрытым также рассматриваются как прокручиваемые ( дополнительная информация ), поэтому вы можете добавить условиепротив этого тоже при необходимости:

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

Объяснение: Хитрость в том, что попытка прокрутки вниз и возврата назад не будет отображаться браузером.Самая верхняя функция также может быть записана следующим образом:

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;
}
1 голос
/ 13 октября 2016

Вот улучшенная версия ответа Эвана, которая, кажется, правильно учитывает логику переполнения.

            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 голос
/ 07 августа 2018

Я собираюсь расширить это еще больше для тех бедных душ, которые, как и я, используют одну из современных js фреймворков, а не JQuery и были полностью заброшены людьми из этой ветки:

это было написано на 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,
) {}

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 будет div с классом "elem-list", который стилизован в css или scss, чтобы иметь height иoverflow значение, которое не hidden.(так что auto или sroll)

Я запускаю это eval при событии прокрутки, потому что моей конечной целью было иметь "автоматические прокрутки фокуса", которые решали бы, прокручивают ли они весь набор компонентов горизонтально, если сказаноКомпоненты не имеют вертикальной прокрутки, в противном случае прокручивают внутренности только одного из компонентов по вертикали.

, но вы можете поместить eval в другом месте, чтобы он мог быть вызван чем-то другим.

важная вещьпомните, что вы никогда не будете вынуждены возвращаться к использованию JQuery, всегда есть способ получить доступ к тем же функциональным возможностям, которые у него есть, без его использования.

0 голосов
/ 18 августа 2016

Вот мое улучшение: добавлен parseInt.по какой-то странной причине он не работал без него.

// usage: jQuery('#my_div1').hasVerticalScrollBar();
// Credit: /2553010/kak-ya-mogu-proverit-vidna-li-polosa-prokrutki
(function($) {
    $.fn.hasVerticalScrollBar = function() {
        return this.get(0) ? parseInt( this.get(0).scrollHeight ) > parseInt( this.innerHeight() ) : false;
    };
})(jQuery);
0 голосов
/ 22 декабря 2017

Большинство представленных ответов приблизили меня к тому месту, где я должен был быть, но не совсем там.

Мы в основном хотели оценить, будут ли полосы прокрутки видны в нормальной ситуации с помощью этогоопределение означает, что размер элемента тела больше, чем порт просмотра.Это не было представлено решение, поэтому я представляю его.

Надеюсь, это кому-нибудь поможет!

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

По сути, у нас есть функция hasScrollbar, но возвращаемая, если запрошенный элемент больше, чем порт представления.Для просмотра размера порта мы просто использовали $(window).height().Быстрое сравнение этого с размером элемента дает правильные результаты и желаемое поведение.

0 голосов
/ 14 февраля 2018

Найти родительский элемент текущего элемента с вертикальной прокруткой или телом.

$.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 голосов
/ 24 июня 2017

Работает на Chrome , Edge , Firefox и Opera , по крайней мере, в новых версиях.

Использование 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());
        }
    }
}

Возвращает функцию. Сделано так, чтобы один раз установить тело и нижний колонтитул.

А затем установите это, когда документ будет готов.

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