Проверьте, есть ли у элемента HTML полосы прокрутки - PullRequest
94 голосов
/ 03 февраля 2011

Какой самый быстрый способ проверить, есть ли у элемента полосы прокрутки?

Конечно, нужно проверить, больше ли элемент, чем его область просмотра, что можно легко сделать, проверив эти два значения:

el.scrollHeight > el.offsetHeight || el.scrollWidth > el.offsetWidth

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

Вопрос

Как проверить полосы прокрутки в 1 кросс-браузер и 2 только путь javascript (как в no jQuery )?

только Javascript, потому что мне нужны как можно меньшие накладные расходыПотому что я хотел бы написать очень быстрый фильтр селектора jQuery

// check for specific scrollbars
$(":scrollable(x/y/both)")

// check for ANY scrollbar
$(":scrollable")

Полагаю, мне нужно было бы проверить настройки стиля overflow, но как мне это сделать кросс-браузерным способом?

Дополнительное редактирование

Не только overflow настройки стиля.Проверка наличия у элемента полосы прокрутки не так тривиальна, как кажется.Первая формула, которую я написал выше, работает хорошо, когда элемент не имеет границы, но когда он имеет (особенно когда граница имеет значительную ширину), размер offset может быть больше, чем размер scroll, но элемент все еще можетбыть прокручиваемымНа самом деле нам нужно вычесть границы из измерения offset, чтобы получить фактический прокручиваемый видовой экран элемента и сравнить его с размером scroll.

Для дальнейшего использования

:scrollable jQuery filter selectorвходит в мой плагин .scrollintoview() jQuery.Полный код можно найти в моем блоге , если кому-то это нужно.Несмотря на то, что он не дал реального решения, код Soumya значительно помог мне решить проблему.Он указал мне правильное направление.

Ответы [ 10 ]

89 голосов
/ 18 февраля 2011

Я нашел это где-то пару недель назад. У меня это сработало.

var div = document.getElementById('container_div_id');

var hasHorizontalScrollbar = div.scrollWidth > div.clientWidth;
var hasVerticalScrollbar = div.scrollHeight > div.clientHeight;

/* you'll get true/false */
16 голосов
/ 03 февраля 2011

Попробуйте:

Для вертикальной полосы прокрутки

el.scrollHeight> el.clientHeight

Для горизонтальной полосы прокрутки

el.scrollWidth> el.clientWidth

Я знаю, что это работает как минимум для IE8 и Firefox 3.6+.

14 голосов
/ 03 февраля 2011

Это может показаться (или быть) немного хакерским, но вы можете проверить свойства scrollTop и scrollLeft.

Если они больше 0, вы знаете, что есть полосы прокрутки. Если они равны 0, тогда установите их на 1 и снова протестируйте, чтобы увидеть, получите ли вы результат 1. Затем установите их обратно на 0.

Пример: http://jsfiddle.net/MxpR6/1/

function hasScroll(el, direction) {
    direction = (direction === 'vertical') ? 'scrollTop' : 'scrollLeft';
    var result = !! el[direction];

    if (!result) {
        el[direction] = 1;
        result = !!el[direction];
        el[direction] = 0;
    }
    return result;
}

alert('vertical? ' + hasScroll(document.body, 'vertical'));
alert('horizontal? ' + hasScroll(document.body, 'horizontal'));

Я считаю, что для IE есть другое свойство, поэтому я обновлю его через минуту.

РЕДАКТИРОВАТЬ: Похоже, что IE может поддерживать это свойство. (Я не могу проверить IE сейчас.)

http://msdn.microsoft.com/en-us/library/ms534618(VS.85).aspx

13 голосов
/ 27 апреля 2016

Вот еще одно решение:

Как указали несколько человек, простого сравнения offsetHeight и scrollHeight недостаточно, поскольку они отличаются для элементов со скрытым переполнением и т. Д., У которых все еще нет полос прокрутки. Поэтому здесь я также проверяю, является ли переполнение прокруткой или авто для вычисленных стилей для элемента:

var isScrollable = function(node) {
  var overflowY = window.getComputedStyle(node)['overflow-y'];
  var overflowX = window.getComputedStyle(node)['overflow-x'];
  return {
    vertical: (overflowY === 'scroll' || overflowY === 'auto') && node.scrollHeight > node.clientHeight,
    horizontal: (overflowX === 'scroll' || overflowX === 'auto') && node.scrollWidth > node.clientWidth,
  };
}
6 голосов
/ 22 июля 2011

Возможно, я немного опоздал на вечеринку, но ...

Я полагаю, вы можете обнаружить полосы прокрутки с e.offsetWidth и e.clientWidth.Ширина смещения включает границы и полосы прокрутки, отступы и ширину.Ширина клиента включает отступы и ширину.Пожалуйста, смотрите:

https://developer.mozilla.org/en/DOM/element.offsetWidth (второе изображение) https://developer.mozilla.org/en/DOM/element.clientWidth (второе изображение)

Вам необходимо проверить:

  1. или нет элемент имеет переполнение, установленное на auto / scroll (включая overflowX / Y) с использованием стиля computed / cascaded / current.
  2. Если элемент имеет переполнение, установленное на auto / scroll.Установите offsetWidth и clientWidth.
  3. Если clientWidth меньше, чем offsetWidth - правая граница (найденная снова через вычисленный / каскадный / текущий стиль), то вы знаете, что у вас есть полоса прокрутки.

Сделайте то же самое для вертикали (offset / clientHeight).

IE7 сообщает значение clientHeight 0 для некоторых элементов (я не проверял почему), поэтому вам всегда нужна первая проверка переполнения.

Надеюсь, это поможет!

2 голосов
/ 27 апреля 2018

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

Так как рендеринг в браузере не очень частый, вы можете проверить наличие прокрутки с изменением прокрутки и затем установить его обратно:

const hasScrollBar = (element) => {
  const {scrollTop} = element;

  if(scrollTop > 0) {
    return true;
  }

  element.scrollTop += 10;

  if(scrollTop === element.scrollTop) {
    return false;
  }

  // undoing the change
  element.scrollTop = scrollTop;
  return true;
};
1 голос
/ 31 октября 2013

Просто возиться здесь, так как ни одно из перечисленных выше решений для меня не сработало (пока) Я нашел некоторый успех в сравнении высоты прокрутки Div с его смещениемHeight

var oh = $('#wrapDiv').get(0).offsetHeight;
var sh = $('#wrapDiv').get(0).scrollHeight;

Кажется, это дает мне точное сравнение ... пока. Кто-нибудь знает, законно ли это?

0 голосов
/ 21 декабря 2017

Для IE11 (Internet Explorer 11) Мне пришлось изменить логику на:

// Subtract 3 (a small arbitrary number) to allow for IE reporting a difference of 1 when no scrollbar is present
var hasVerticalScrollbar = div.scrollHeight - 3 > div.clientHeight;

Это связано с тем, что IE сообщает значение scrollHeight на 1 больше, чем clientHeight, когда полоса прокрутки отсутствует, нопримерно на 9 больше при наличии полосы прокрутки

0 голосов
/ 15 августа 2017

ни один из этих ответов не верен.Вы должны использовать это:

var div = document.getElementById('container_div_id');

var hasHorizontalScrollbar = (div.offsetWidth > div.clientWidth);
var hasVerticalScrollbar = (div.offsetHeight > div.clientHeight);
0 голосов
/ 03 февраля 2011

Добавьте элемент шириной 100%.Затем установите переполнение скрытым.Если вычисленный стиль элемента (из jQ) изменяется, родительский элемент имеет полосу прокрутки.

РЕДАКТИРОВАТЬ: кажется, вам нужен кросс-браузерный метод, такой как getComputedStyle .Попробуйте:

function getCSS(_elem, _style)
{
    var computedStyle;
    if (typeof _elem.currentStyle != 'undefined')
        computedStyle = _elem.currentStyle;
    else
        computedStyle = document.defaultView.getComputedStyle(_elem, null);
    return computedStyle[_style];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...