Перевірте, чи має елемент HTML прокрутки


113

Який найшвидший спосіб перевірити, чи є у елемента смуги прокрутки?

Звичайно, перевірити, чи більший елемент, ніж його вікно перегляду, що легко зробити, перевіривши ці два значення:

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 включений у мій .scrollintoview()плагін jQuery. Повний код можна знайти в моєму блозі, якщо комусь це потрібно. Навіть незважаючи на те, що він не надав фактичного рішення, код Soumya значно допоміг мені вирішити проблему. Це вказувало мені в правильному напрямку.

Відповіді:


118

Я знайшов це десь пару тижнів тому. Це працювало для мене.

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

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

/* you'll get true/false */

12
Ви, очевидно, мали спрощений приклад. Що робити, якщо ваш контейнер overflow:hiddenвстановлений на ньому? Зайвого вмісту буде, але його все ще не можна прокручувати. Проблема далеко не така проста, як може здатися.
Роберт Коритник

7
Це може бути не прийнятим рішенням, але воно працювало для мене. Я не впевнений, чому ви прокручували б її, якщо вона прихована.
vol7ron

Це може бути не прийнятим рішенням, але воно працювало для мене. Роберт, для цих випадків ви не могли також отримати властивість переповнення css для перевірки цих випадків (наприклад div.scrollHeight>div.clientHeight && !(div.style.overflow && div.style.overflow == 'hidden'))?
vol7ron

7
У багатьох випадках це не вдається. Якщо ваш елемент має переповнення: видимий; ширина: 200px; і у нього є дитина з шириною 500 пікселів, ваш елемент не має смуг прокрутки, але має ширину прокрутки 500 пікселів та ширину клієнта 200 пікселів.
Джозеф Леннокс

1
Якщо переповнення видиме чи приховане, зазвичай немає смуг прокрутки.
Hubert Grzeskowiak

16

Спробуйте:

Для вертикальної смуги прокрутки

el.scrollHeight> el.clientHeight

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

el.scrollWidth> el.clientWidth

Я знаю, що це працює як мінімум для IE8 та Firefox 3.6+.


2
Я вказав це так, що це говорить про те, що певний елемент є більшим, ніж здається, але це не означає, що він відображає смуги прокрутки. Це також може бути, overflow:hiddenі його більше не можна прокручувати.
Роберт Коритник

1
І перевірка значень clientHeight / clientWidth не дає хороших результатів, оскільки елементи можуть мати і межі, які не включені в цей захід. Перевір мою формулу. Це працює краще, ніж ваше.
Роберт Коритник

Це правда щодо використання offsetHeight / offsetWidth для перевірки смуг прокрутки замість clientHeight / clientWidth. Дякуємо, що вказали на це.
Гері

@RobertKoritnik - так що просто перевірте, чи є overflow:hiddenв ньому конкретний елемент ... на мою думку, це все-таки правильна відповідь, оскільки це найпростіша.
vsync

14

Це може здатися (або бути) трохи хакітським, але ви можете перевірити 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


Набагато простіше перевірити смуги прокрутки, якщо порівнювати offsetHeightі clientHeight. Остання завжди менша за розміром смуги прокрутки, коли присутній смуга прокрутки.
Роберт Коритник

@Robert: Не впевнений, що простіше, але я бачу, як це працює. Тоді я припускаю, що якщо у якогось елемента є overflow:scroll, ви хочете, щоб він повідомлявся як прокручуваний, незалежно від того, включені чи ні смуги прокрутки. Звичайно, моє рішення може мати проблеми, якщо додається подія onscroll.
користувач113716

Не зовсім. Якщо ви перевірите мій плагін jQuery, я повинен знайти справжнього предка, який можна прокручувати, інакше я не можу прокрутити елемент до перегляду.
Роберт Коритник

8
@RobertKoritnik Неправда; деякі веб-переглядачі можуть мати смуги прокрутки, які не зменшують ширину. Наприклад, на ОС X X. Або торкніться пристроїв.
daniel.gindi

1
завжди повертайте помилково
Fatih Erol

14

Ось ще одне рішення:

Як зауважило декілька людей, просто порівнювати 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,
  };
}

Якщо overflow*це scrollзавжди буде смуга прокрутки, так що я думаю , що ви хочете vertical: overflowY === 'scroll' || overflowY === 'auto' && node.scrollHeight > node.clientHeight, і т.д. (тобто зняти дужки так scroll*проти client*перевіряється тільки коли overflow*є auto). Інакше це виявляється найбільш правильним рішенням.
Джейк

@Jake Якщо scrollHeight <clientHeight при переливі прокрутки, прокрутки будуть там, але вони будуть відключені (тобто елемент не можна прокручувати). Тому я думаю, це залежить від програми. Ваша модифікація дійсна, ви просто хочете перевірити, чи є смуги прокрутки, не має значення стан. Для мене, коли я придумав це, я шукав впровадити автоскролл для компонента, тому відключення смуг прокрутки марно в цьому випадку. Це також, мабуть, стосується цього питання (його потрібно "прокрутити людьми")
lotif

6

Я, можливо, трохи спізнився на вечірку, але ...

Я вважаю, що ви можете виявити смуги прокрутки з e.offsetWidth проти e.clientWidth. Ширина зміщення включає рамки та смуги прокрутки, підкладку та ширину. Ширина клієнта включає прокладку та ширину. Будь ласка, дивіться:

https://developer.mozilla.org/uk/DOM/element.offsetWidth (друге зображення) https://developer.mozilla.org/uk/DOM/element.clientWidth (друге зображення)

Вам потрібно перевірити:

  1. Незалежно від того, чи має елемент переповнення встановлено для автоматичного / прокручування (включаючи overflowX / Y), використовуючи обчислений / каскадний / поточний стиль.
  2. Якщо елемент має переповнення, встановлений для автоматичного / прокручування. Встановіть offsetWidth та clientWidth.
  3. Якщо ширина клієнта менша, ніж межа офсетної ширини - права межа (знайдена знову через стиль обчисленого / каскадного / поточного), то ви знаєте, що у вас є смуга прокрутки.

Зробіть те саме для вертикалі (зміщення / висота клієнта).

IE7 повідомляє clientHeight 0 для деяких елементів (я не перевіряв чому), тому вам завжди потрібна перша перевірка переповнення.

Сподіваюся, це допомагає!


3

У випадку перевірки існування прокрутки є декілька проблем, одна з яких полягає в тому, що у 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

Тільки возитися тут, як жодне з перерахованих вище рішень не працювало для мене (поки що). Я знайшов певний успіх порівнявши висоту прокрутки Div з її зсувом

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

Здається, це дає мені точне порівняння ... поки що. Хтось знає, чи це законно?


2
Я думаю , що ви хочете scrollHeight і clientHeight: stackoverflow.com/questions/4106538 / ...
багатий Ремер

1

Для 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

Якщо вам потрібно знати, чи є смуга прокрутки для всієї веб-сторінки та з повною підтримкою браузера, ви можете скористатися цим:

const hasScrollbar = document.body.scrollHeight > window.innerHeight

Це важливо використовувати window.innerHeightзамість того, document.body.clientHeightщо в деяких мобільних браузерах clientHeight не отримає розмір адресного рядка, а scrollHeight буде, тому ви отримаєте неправильні розрахунки.


-5

жоден із цих відповідей не є правильним. Ви повинні використовувати це:

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

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

Це було знято з огляду на те, що він отримав копію / вставлений з прийнятої відповіді 6 років тому, і вам не потрібні дужки, щоб перетворити щось на буле.
мото

-6

Додайте всередині нього елемент на 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];
}

1
Якби я вже використовував jQuery для цього, я б краще просто зробити $(el).css("overflow/overflowX/overflowY")і подивитися, чи встановлено він для автоматичного чи прокручування . Але я хотів би уникати використання jQuery.
Роберт Коритник

16
Стилі CSS не будуть вам сказати , є чи ні елемента має скроллбар. Тільки вона чи ні може мати смуги прокрутки. Можливо, знайдете крос-браузерний метод визначення ширини внутрішнього елемента?
Soumya

@ Soumya92: Порівняння розмірів між прокручуваним та фактичним розміром є тривіальним, і я написав це вище ... Все, що мені потрібно перевірити зараз, - це поточне налаштування переповнення певного елемента.
Роберт Коритник

@ Soumya92: саме це мені і потрібно. Це також може бути дуже спрощено, використовуючи coalescecomputedStyle = el.currentStyle || document.defaultView.getComputedStyle(el, null);
Роберт Коритник

Ще одне: наскільки це перехресний браузер? Які браузери це підтримує?
Роберт Коритник
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.