Виявити, чи на сторінці є вертикальна смуга прокрутки?


121

Я просто хочу, щоб простий JQ / JS перевірив, чи поточна сторінка / вікно (не конкретний елемент) має вертикальну смугу прокрутки.

Гуглінг дає мені речі, які здаються надмірно складними саме для цієї основної функції.

Як це можна зробити?

Відповіді:


97
$(document).ready(function() {
    // Check if body height is higher than window height :)
    if ($("body").height() > $(window).height()) {
        alert("Vertical Scrollbar! D:");
    }

    // Check if body width is higher than window width :)
    if ($("body").width() > $(window).width()) {
        alert("Horizontal Scrollbar! D:<");
    }
});

14
+1, але задля точності це лише перевіряє, чи вміст розширюється далі, ніж вікно перегляду. Якщо overflowвластивість параметра bodyвстановлено hiddenдесь уздовж лінії, воно не працюватиме. Хоча встановлення на тілі є вкрай рідкісним.
Pekka

4
Це не працює, якщо висота корпусу відповідає висоті вікна, це в тому випадку, якщо висота doc точно відповідає області перегляду, тож додається горизонтальна смуга прокрутки . Це змусить верт. смуга прокрутки, але висота doc / body / window однакова; він НЕ буде попереджати "вертикальну смугу прокрутки", навіть тому, що вона є.
Зупиніть наклеп на Моніку Селіо

2
Просто подумав, що я згадаю, що мені довелося використовувати $(document)замість цього $("body"), це працювало для мене, коли тіло не було (у мене є абсолютний позиціонований контейнер із співвідношенням сторін по ширині / висоті)
am_

1
Я маю сторінку звіту в браузері Chrome, де вона спочатку відображає смугу прокрутки і зникає за лічені мілісекунди, що схоже на поведінку браузера, оскільки я її не програмував. Тож ця функція повертається завжди в моєму випадку ..
Даш,

@TiuTalk для мене $ ("body"). Висота () & $ (вікно) .height () дає те саме значення, натомість я використовую $ (document) .height ()> $ (window) .height (), для якого він працює я.
SarangK

77

спробуйте це:

var hasVScroll = document.body.scrollHeight > document.body.clientHeight;

Це покаже лише вам, якщо вертикальна прокруткаВисота більша за висоту вмісту, який видно. hasVScrollМінлива міститиме істинне або помилкове.

Якщо вам потрібно зробити більш ретельну перевірку, додайте наступне до коду вище:

// Get the computed style of the body element
var cStyle = document.body.currentStyle||window.getComputedStyle(document.body, "");

// Check the overflow and overflowY properties for "auto" and "visible" values
hasVScroll = cStyle.overflow == "visible" 
             || cStyle.overflowY == "visible"
             || (hasVScroll && cStyle.overflow == "auto")
             || (hasVScroll && cStyle.overflowY == "auto");

1
+1 Приємно! І з необхідним обчисленим стилем (саме тоді я вирішив не брати участь у цьому питанні;)
Pekka

хай так, я обговорював, чи варто докладати додаткових зусиль, щоб написати це, оскільки в багатьох випадках це не потрібно.
Енді Е

1
Це призводить до того, що hasVScroll є істинним, коли overflowY є "видимим", незалежно від того, висота scrollHeight перевищує висоту clientHeight. Може, ти мав на увазі cStyle.overflow === 'scroll'?
BT

5
Наведений вище код не працює. Веб-
Себастьян Лорбер

1
@BT cStyle.overflow == "visible" може показувати смуги прокрутки, коли елементом є document.body. Але це має бути (hasVScroll && cStyle.overflow == "видимий" && element.nodeName == "BODY"). Плюс це потрібно перевірити, cStyle.overflow === 'scroll'як ви вказуєте.
mseifert

44

Я спробував попередню відповідь, і, схоже, не працює $ ("body"). Висота () не обов'язково представляє всю висоту html.

Я виправив рішення таким чином:

// Check if body height is higher than window height :) 
if ($(document).height() > $(window).height()) { 
    alert("Vertical Scrollbar! D:"); 
} 

// Check if body width is higher than window width :) 
if ($(document).width() > $(window).width()) { 
    alert("Horizontal Scrollbar! D:<"); 
} 

18

Давайте повернемо це питання з мертвих;) Існує причина, що Google не дає вам простого рішення. Особливі випадки та химерність браузера впливають на обчислення, і це не так банально, як здається.

На жаль, поки що існують проблеми з викладеними тут рішеннями. Я зовсім не хочу їх зневажати - вони є чудовими відправними точками і стосуються всіх ключових властивостей, необхідних для більш надійного підходу. Але я б не рекомендував копіювати та вставляти код з будь-якої з інших відповідей, оскільки

  • вони не фіксують ефект розміщеного контенту надійним крос-браузером. Відповіді, що ґрунтуються на розмірі тіла, цілком не пропускають (тіло не є початковим зсувом такого змісту, якщо він не розміщений сам). І ці відповіді перевіряють $( document ).width()і .height()стають здобиччю на помилку виявлення розміру документа jQuery .
  • Спираючись на window.innerWidth, якщо підтримує браузер це робить ваш код не виявити смуги прокрутки в мобільних браузерах, де ширина смуги прокрутки зазвичай 0. Вони просто показані тимчасово як оверлей і не займають місця в документі . Збільшення масштабів на мобільних пристроях також стає проблемою в такий спосіб (довга історія).
  • Виявлення може бути відкинуте, коли люди явно встановлюють переповнення як htmlі bodyелемента, що не мають значень за замовчуванням (те, що відбувається потім, мало пов'язане - див. Цей опис ).
  • У більшості відповідей набивання тіла, межі або поля не виявляються і не спотворюють результати.

Я витратив більше часу, ніж я міг би уявити, щоб знайти рішення, яке "просто працює" (кашель). Алгоритм я придумав тепер є частиною плагіна, jQuery.isInView , який виставляє на .hasScrollbarметод . Побачте джерело, якщо бажаєте.

У випадку, коли ви повністю контролюєте сторінку та не маєте справи з невідомими CSS, використання плагіна може бути надмірним - адже ви знаєте, які крайові випадки застосовуються, а які ні. Однак якщо вам потрібні надійні результати у невідомому середовищі, я не думаю, що намічених тут рішень буде недостатньо. Вам краще використовувати перевірений плагін - мій або хтось інший.


Дякую. Досить складно! Якщо ви не хочете / не повинні бути сумісними назад, можливо, є більш просте рішення для браузерів html5? Я маю на увазі, можливо, кодери браузера / w3c були досить приємними, щоб просто сказати нам, чи є елементи прокрутки чи немає на елементі? ;-)
Лев

1
@Leo Не те, що я знаю. Ну, є window.scrollbarsоб'єкт , який має одну властивість, visible. Звучить багатообіцяюче, але ні. Він не підтримується в IE, включаючи IE11. І це просто говорить вам , що є смуга прокрутки - але не один , який. Дивіться тестову сторінку тут .
хеш-обмін

Дякую @hashchange. Звучить неймовірно нерозумно, що він просто повідомляє, чи є смуга прокрутки, тому я думаю, що це ще якийсь тест. Трохи перспективний, хоча. ;-)
Лев

1
@BT Добре, чудово. Тепер дозвольте повести вас до входу у кролячу нору;) Ось демонстрація, де вмісту недостатньо, щоб заповнити вікно. Виявлення працює у FF, але не працює в Chrome. І ось ще одна демонстрація, де позиціонований елемент розміщений далеко внизу сторінки. Виявлення працює в Chrome, але не працює у FF.
хеш-обмін

1
@BT І я думаю, ми можемо потрапити в купу дивних режимів відмов, коли ми почнемо грати з налаштуваннями переповнення, оскільки їх поведінка трохи дивна , але я зупинився саме там.
hashchange

15

Цей працює для мене:

function hasVerticalScroll(node){
    if(node == undefined){
        if(window.innerHeight){
            return document.body.offsetHeight> window.innerHeight;
        }
        else {
            return  document.documentElement.scrollHeight > 
                document.documentElement.offsetHeight ||
                document.body.scrollHeight>document.body.offsetHeight;
        }
    }
    else {
        return node.scrollHeight> node.offsetHeight;
    }
}

Для тіла просто використовуйте hasVerticalScroll().


Це єдина відповідь у цій темі, яка працює на моєму Chrome
Nertan Lucian

clientHeightтут краще offsetHeight. В іншому випадку ви можете мати товсту облямівку, а повернення немає, коли панель прокрутки є.
theicfire


3

Як не дивно, жодне з цих рішень не повідомляє, чи на сторінці є вертикальна смуга прокрутки.

window.innerWidth - document.body.clientWidthдасть вам ширину смуги прокрутки. Це повинно працювати в будь-якому IE9 + (не перевірено в менших браузерах). (Або строго відповісти на питання,!!(window.innerWidth - document.body.clientWidth)

Чому? Скажімо, у вас є сторінка, де вміст вище, ніж висота вікна, і користувач може прокручувати вгору / вниз. Якщо ви користуєтеся Chrome на Mac без підключеної миші, користувач не побачить смугу прокрутки. Підключіть мишку і з’явиться панель прокрутки. (Зауважте, цю поведінку можна відмінити, але це AFAIK за замовчуванням).


Пояснення поведінки Chrome-Mouse допомогло мені зрозуміти, що я вважаю непослідовною поведінкою. Дякую!
theisof

2

Я знайшов рішення ваніли

var hasScrollbar = function() {
  // The Modern solution
  if (typeof window.innerWidth === 'number')
    return window.innerWidth > document.documentElement.clientWidth

  // rootElem for quirksmode
  var rootElem = document.documentElement || document.body

  // Check overflow style property on body for fauxscrollbars
  var overflowStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowStyle = rootElem.currentStyle.overflow

  overflowStyle = overflowStyle || window.getComputedStyle(rootElem, '').overflow

    // Also need to check the Y axis overflow
  var overflowYStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowYStyle = rootElem.currentStyle.overflowY

  overflowYStyle = overflowYStyle || window.getComputedStyle(rootElem, '').overflowY

  var contentOverflows = rootElem.scrollHeight > rootElem.clientHeight
  var overflowShown    = /^(visible|auto)$/.test(overflowStyle) || /^(visible|auto)$/.test(overflowYStyle)
  var alwaysShowScroll = overflowStyle === 'scroll' || overflowYStyle === 'scroll'

  return (contentOverflows && overflowShown) || (alwaysShowScroll)
}


1
Не працює в IE 11. window.innerWidth & document.documentElement.clientWidth завжди однакові.
NLV

Виправлено це. Ця ж функція працює і для IE 11. Проблема була в цьому - stackoverflow.com/questions/17045132/…
NLV

Я протестував це в Chrome 65 і він працює. Але коли я адаптую його до горизонтальних смуг прокрутки, результат дивний: якщо відображаються і горизонтальна, і вертикальна смуга прокрутки, window.innerWidth > document.documentElement.clientWidthце правда, але window.innerHeight > document.documentElement.clientHeightце не так. Схоже, що в цьому випадку все було навпаки. Я не розробник JS, мені це просто потрібно для тестів Selenium. Я вдячний за підказки.
kriegaex

2
    <script>
    var scrollHeight = document.body.scrollHeight;
    var clientHeight = document.documentElement.clientHeight;
    var hasVerticalScrollbar = scrollHeight > clientHeight;

    alert(scrollHeight + " and " + clientHeight); //for checking / debugging.
    alert("hasVerticalScrollbar is " + hasVerticalScrollbar + "."); //for checking / debugging.
    </script>

Цей підкаже, чи є у вас смуга прокрутки чи ні. Я включив деяку інформацію, яка може допомогти при налагодженні, яка відображатиметься як попередження JavaScript.

Помістіть це в тег сценарію після закриття тегу body.


1

Я написав оновлену версію відповіді Кіса К. Бейкера:

const hasVerticalScroll = (node) => {
  if (!node) {
    if (window.innerHeight) {
      return document.body.offsetHeight > window.innerHeight
    }
    return (document.documentElement.scrollHeight > document.documentElement.offsetHeight)
      || (document.body.scrollHeight > document.body.offsetHeight)
  }
  return node.scrollHeight > node.offsetHeight
}

if (hasVerticalScroll(document.querySelector('body'))) {
  this.props.handleDisableDownScrollerButton()
}

Функція повертає true чи false, залежно від того, на сторінці є вертикальна смуга прокрутки чи ні.

Наприклад:

const hasVScroll = hasVerticalScroll(document.querySelector('body'))

if (hasVScroll) {
  console.log('HAS SCROLL', hasVScroll)
}

1

я використовую

public windowHasScroll()
{
    return document.body.clientHeight > document.documentElement.clientHeight;
}

1

Просто порівняйте ширину кореневого елемента документів (тобто елемента html) з внутрішньою частиною вікна:

if ((window.innerWidth - document.documentElement.clientWidth) >0) console.log('V-scrollbar active')

Якщо вам також потрібно знати ширину смуги прокрутки:

vScrollbarWidth = window.innerWidth - document.documentElement.clientWidth;

0

Інші рішення не працювали в одному з моїх проектів, і я закінчував перевірку властивості css overflow

function haveScrollbar() {
    var style = window.getComputedStyle(document.body);
    return style["overflow-y"] != "hidden";
}

але він працюватиме лише у випадку, якщо на панелі прокрутки зникне, змінивши опору, вона не працюватиме, якщо вміст дорівнює або менший, ніж вікно.

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