Как я могу проверить, видна ли полоса прокрутки? - 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 ]

359 голосов
/ 27 января 2011

маленький плагин для него.

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

используйте это так,

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

протестировано работает на Firefox, Chrome, IE6,7,8

, но не работает должным образом на body селекторе тегов

демо


Редактировать

Я обнаружил, что когда у вас есть горизонтальная полоса прокрутки, которая вызывает появление вертикальной полосы прокрутки, эта функция не работает ....

Я нашел другое решение ... используйте clientHeight

return this.get(0).scrollHeight > this.get(0).clientHeight;
50 голосов
/ 13 мая 2011

Возможно, более простое решение.

if ($(document).height() > $(window).height()) {
    // scrollbar
}
41 голосов
/ 26 января 2012

Я должен немного изменить сказанное Рейгелем:

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

innerHeight подсчитывает высоту элемента управления, его верхние и нижние отступы

33 голосов
/ 22 марта 2015

Вы можете сделать это, используя комбинацию атрибутов Element.scrollHeight и Element.clientHeight.

Согласно MDN:

Атрибут Element.scrollHeight только для чтения - это измерение высоты содержимого элемента, включая содержимое, не видимое на экране из-за переполнения. Значение scrollHeight равно минимальному значению clientHeight, которое потребуется элементу для размещения всего содержимого в точке обзора без использования вертикальной полосы прокрутки. Включает заполнение элемента, но не его поле.

And:

Свойство Element.clientHeight только для чтения возвращает внутреннюю высоту элемента в пикселях, включая отступы, но не высоту горизонтальной полосы прокрутки, границы,или margin.

clientHeight можно рассчитать как высоту CSS + заполнение CSS - высота горизонтальной полосы прокрутки (если имеется).

Следовательно, элемент будет отображать полосу прокрутки, если высота прокруткибольше, чем рост клиента, поэтому ответ на ваш вопрос:

function scrollbarVisible(element) {
  return element.scrollHeight > element.clientHeight;
}
24 голосов
/ 29 января 2014

Это расширяет ответ @ Рейгеля.Он вернет ответ для горизонтальной или вертикальной полосы прокрутки.

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

Пример:

element.hasScrollBar()             // Returns { vertical: true/false, horizontal: true/false }
element.hasScrollBar().vertical    // Returns true/false
element.hasScrollBar().horizontal  // Returns true/false
12 голосов
/ 27 января 2011

Вам нужно element.scrollHeight .Сравните это с $(element).height().

7 голосов
/ 07 августа 2012

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

  1. переполнение: [прокрутка | авто]
  2. overflow-x: [scroll | auto]
  3. overflow-y: [scroll | auto]

Я хотел найти ближайшего прокручиваемого родителя другого элемента, поэтому я также написал еще один маленький плагин jQuery, чтобы найти ближайшего родителя с переполнением.

Это решение, вероятно, не работает лучше, но, похоже, работает. Я использовал его вместе с плагином $ .scrollTo. Иногда мне нужно знать, находится ли элемент внутри другого прокручиваемого контейнера. В этом случае я хочу прокрутить родительский прокручиваемый элемент против окна.

Мне, вероятно, следовало бы обернуть это в один плагин и добавить селектор psuedo как часть плагина, а также предоставить «ближайший» метод для поиска ближайшего (родительского) прокручиваемого контейнера.

В любом случае ... вот оно.

$. IsScrollable Плагин 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') jQuery псевдоселектор:

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

$. Scrollableparent () Плагин jQuery:

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

Реализация довольно проста

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

ОБНОВЛЕНИЕ: Я обнаружил, что Роберт Коритник уже придумал гораздо более мощный: прокручиваемый псевдоселектор, который будет определять прокручиваемые оси и высоту прокручиваемых контейнеров, как часть его $ .scrollintoview () Плагин jQuery. плагин scrollintoview

Вот его причудливый псевдоселектор (реквизит):

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

    }

});
6 голосов
/ 09 марта 2012

Первое решение выше работает только в IE Второе решение выше работает только в FF

Эта комбинация обеих функций работает в обоих браузерах:

//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");
}​
  • Завернуть в документ готов
  • monitorWidth1: div, в котором для переполнения установлено значение auto
  • mtc: контейнерный контейнер внутри monitorWidth1
  • AdjustOverflowWidth: класс css, применяемый к элементу #mtc, когда полоса прокрутки активна * Используйте оповещение для тестирования кросс-браузера, а затем закомментируйте окончательный производственный код.

НТН

5 голосов
/ 08 марта 2017

(scrollWidth / Height - clientWidth / Height) является хорошим индикатором наличия полосы прокрутки, но во многих случаях дает ложный положительный ответ.если вам нужно быть точным, я бы предложил использовать следующую функцию.вместо того, чтобы пытаться угадать, является ли элемент прокручиваемым, вы можете прокрутить его ...

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>
4 голосов
/ 04 октября 2016

Тьфу, все ответы здесь неполны, и давайте прекратим использовать jquery в SO ответах, пожалуйста. Проверьте документацию jquery, если хотите получить информацию о jquery.

Вот обобщенная функция чистого javascript для проверки наличия или отсутствия у элемента ползун прокрутки:

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