Проверьте, имеет ли элемент HTML полосы прокрутки

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

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

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

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

Вопрос

Как проверить полосы прокрутки в перекрестном браузере 1 и 2 только для javascript (как в случае без jQuery)?

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

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

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

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

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

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

Для справок в будущем

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

Ответ 1

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

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

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

/* you'll get true/false */

Ответ 2

Try:

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

el.scrollHeight > el.clientHeight

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

el.scrollWidth > el.clientWidth

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

Ответ 3

Это может показаться (или быть) немного хакерским, но вы можете проверить свойства 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 существует другое свойство, поэтому я обновляюсь через минуту.

EDIT: Появляется, как будто IE может поддерживать это свойство. (Я не могу проверить IE сейчас.)

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

Ответ 4

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

Как отметили несколько человек, просто сравнивать 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,
  };
}

Ответ 5

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

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

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

Вам нужно проверить:

  • Независимо от того, установлен ли элемент переполнения для автоматического/прокрутки (включая overflowX/Y) с использованием вычисленного/каскадного/текущего стиля.
  • Если элемент имеет переполнение, установленное на авто/прокрутку. Установите offsetWidth и clientWidth.
  • Если clientWidth меньше, чем offsetWidth - правая граница (найденная снова через вычисленный/каскадный/текущий стиль), то вы знаете, что у вас есть полоса прокрутки.

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

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

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

Ответ 6

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

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

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

Ответ 7

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

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

var hasHorizontalScrollbar = (div.offsetWidth > div.clientWidth);
var hasVerticalScrollbar = (div.offsetHeight > div.clientHeight);

Ответ 8

Для 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 больше, если присутствует полоса прокрутки.

Ответ 9

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

EDIT: Кажется, вам нужен кросс-браузерный метод, например 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];
}