Как я могу получить размеры полосы прокрутки браузера?

165

Как определить высоту горизонтальной полосы прокрутки или ширину вертикальной полосы прокрутки в JavaScript?

glmxndr
источник
2
Вот фрагмент от автора плагина JQuery Dimension. github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/… может быть поздно, чтобы дать это решение, но оно кажется мне лучшим, IMO.
Яник Рошон
Посмотрите на это решение: davidwalsh.name/detect-scrollbar-width
GibboK
@GibboK - это решение терпит неудачу - offsetWidth == clientWidth, поэтому оно всегда равно нулю. Это проверено в крайнем IE && Chrome.
beauXjames
1
@beauXjames странно, это работает для меня на FF
GibboK
Этот вопрос возникает в ситуации, когда полоса прокрутки находится в неправильном месте (где-то посередине экрана). В этой ситуации вы, вероятно, не хотите показывать полосу прокрутки. В большинстве случаев я обнаружил, что iScroll является идеальным решением, не зависящим от дизайна: iscrolljs.com
JoostS

Ответы:

140

Из блога Александра Гомеса я не пробовал. Дайте мне знать, если это работает для вас.

function getScrollBarWidth () {
  var inner = document.createElement('p');
  inner.style.width = "100%";
  inner.style.height = "200px";

  var outer = document.createElement('div');
  outer.style.position = "absolute";
  outer.style.top = "0px";
  outer.style.left = "0px";
  outer.style.visibility = "hidden";
  outer.style.width = "200px";
  outer.style.height = "150px";
  outer.style.overflow = "hidden";
  outer.appendChild (inner);

  document.body.appendChild (outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild (outer);

  return (w1 - w2);
};
Мэтью Вайнс
источник
2
Идея гениальна, я определенно создаю класс MooTools на основе этого.
Райан Флоренс
Да, я получил тот же результат Google. :) Я стараюсь держать вас в курсе.
glmxndr
если вы измените свою тему на другую с полосами прокрутки разных размеров, какое отклонение будет рассчитано для фактического?
Мэтью Вайнс
1
см. здесь для перекрестной ссылки: stackoverflow.com/questions/3417139/…
Яник Рочон
6
Возвращает разные значения с разным масштабированием страницы. Win7, Opera, FF.
Колюня
79

Используя jQuery, вы можете сократить ответ Мэтью Вайнса на:

function getScrollBarWidth () {
    var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
        widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
    $outer.remove();
    return 100 - widthWithScroll;
};
Джошуа Бамбрик
источник
2
Спасибо, это решение очень чисто!
Jherax
4
Будет ли это решение действительно более понятным, если весь исходный код JQuery будет скопирован перед этим? Потому что это в значительной степени то, что делает это решение. На этот вопрос не задавался ответ в JQuery, и вполне возможно и эффективно выполнить эту задачу без использования библиотеки.
DaemonOfTheWest
5
Если вы уже используете JQuery, то комментарий Daemon не имеет значения. Да, добавлять JQuery просто для этого было бы бессмысленно, но для тех, кто уже использует JQuery в своем проекте, это гораздо «более простое» решение, чем принятое.
Тайлер
25

Это единственный найденный мной скрипт, который работает в браузерах webkit ... :)

$.scrollbarWidth = function() {
  var parent, child, width;

  if(width===undefined) {
    parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');
    child=parent.children();
    width=child.innerWidth()-child.height(99).innerWidth();
    parent.remove();
  }

 return width;
};

Свернутая версия:

$.scrollbarWidth=function(){var a,b,c;if(c===undefined){a=$('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');b=a.children();c=b.innerWidth()-b.height(99).innerWidth();a.remove()}return c};

И вы должны позвонить, когда документ будет готов ... так

$(function(){ console.log($.scrollbarWidth()); });

Протестировано 2012-03-28 на Windows 7 в последних версиях FF, Chrome, IE & Safari и работает на 100%.

источник: http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth

Ян Шафранек
источник
13
ширина будет ВСЕГДА === неопределена в этом коде. с таким же успехом можно поступить, если (правда) {...}
sstur
3
Исправление: всегдаwidth будет === undefined при первом вызове функции. При последующих вызовах функции уже установлено, что проверка просто предотвращает необходимость повторного запуска вычислений без необходимости. width
MartinAnsty
17
@MartinAnsty Но переменная [width] объявлена внутри функции, поэтому она создается заново каждый раз, когда вы вызываете функцию.
MadSkunk
4
@MartinAnsty, если вы посмотрите на источник , он объявлен во внешнем закрытии.
TheCloudlessSky
3
Просто чтобы подчеркнуть точку зрения @sstur и @TheCloudlessSky, приведенный выше код не совпадает с кодом в плагине Бена Алмана, и он не будет кэшировать результат width, а скорее пересчитывать его каждый раз. Это работает, но это ужасно неэффективно. Пожалуйста, сделайте миру одолжение и используйте правильную версию в плагине Алмана.
hashchange
24

если вы ищете простую операцию, просто смешайте обычный dom js и jquery,

var swidth=(window.innerWidth-$(window).width());

возвращает размер полосы прокрутки текущей страницы. (если он виден или еще вернет 0)

Beep.Exe
источник
10
Это не удастся, если в окне не было полос прокрутки (большой монитор или маленькая страница / приложение)
Фарид Нури Нешат
1
это совершенно то, что я хотел
azerafati
16
window.scrollBarWidth = function() {
  document.body.style.overflow = 'hidden'; 
  var width = document.body.clientWidth;
  document.body.style.overflow = 'scroll'; 
  width -= document.body.clientWidth; 
  if(!width) width = document.body.offsetWidth - document.body.clientWidth;
  document.body.style.overflow = ''; 
  return width; 
} 
Джош Стодола
источник
Сначала попробовал принятый ответ, но обнаружил, что это больше не работает в Firefox на Windows 8. Перешел на этот вариант, который прекрасно справляется со своей задачей.
Matijs
1
Код короче, но браузер должен перерисовать всю страницу, поэтому он очень медленный.
Адриан Мэйр
11

Для меня самый полезный способ был

(window.innerWidth - document.getElementsByTagName('html')[0].clientWidth)

с ванильным JavaScript.

введите описание изображения здесь

Андрес Морено
источник
Спасибо, Стивен-Кенди. Приветствие.
Андре Морено
3
Как раз то, что мне было нужно. Одно предложение: второй член можно заменить на document.documentElement.clientWidth. documentElementболее четко и четко выражает намерение получить <html>элемент.
Ян Миксовский
9

Я нашел простое решение, которое работает для элементов внутри страницы, а не самой страницы: $('#element')[0].offsetHeight - $('#element')[0].clientHeight

Это возвращает высоту полосы прокрутки оси X.

Мемет Олсен
источник
Великий!! Вы сделали мой день :) Он также работает с ".offsetWidth" и ".clientWidth" для полос прокрутки по оси Y.
Полоссон,
1
К сожалению, не совсем надежно, по крайней мере, для ширины. Кажется, что .clientWidth включает половину ширины полосы прокрутки в FireFox и Chrome под Linux.
Майкл Шепер
6

Из блога Дэвида Уолша :

// Create the measurement node
var scrollDiv = document.createElement("div");
scrollDiv.className = "scrollbar-measure";
document.body.appendChild(scrollDiv);

// Get the scrollbar width
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
console.info(scrollbarWidth); // Mac:  15

// Delete the DIV 
document.body.removeChild(scrollDiv);
.scrollbar-measure {
	width: 100px;
	height: 100px;
	overflow: scroll;
	position: absolute;
	top: -9999px;
}

Дает мне 17 на моем сайте, 14 здесь, на Stackoverflow.

mpen
источник
4

Если у вас уже есть элемент с полосами прокрутки, используйте:

function getScrollbarHeight(el) {
    return el.getBoundingClientRect().height - el.scrollHeight;
};

Если панель horzintscroll не присутствует, функция перезапустится 0

монс дроид
источник
Это лучший ответ пока. KISS управляет всеми
MarcD
4

Вы можете определить windowполосу прокрутки, documentкак показано ниже, используя jquery + javascript:

var scrollbarWidth = ($(document).width() - window.innerWidth);
console.info("Window Scroll Bar Width=" + scrollbarWidth );
Бхуван Прасад Упадхьяй
источник
Обратите внимание, что innerWidth для IE9 +. В противном случае отличное решение.
Пол Тингбо
3

В Antiscroll.jsкоде это делается так:

function scrollbarSize () {
  var div = $(
      '<div class="antiscroll-inner" style="width:50px;height:50px;overflow-y:scroll;'
    + 'position:absolute;top:-200px;left:-200px;"><div style="height:100px;width:100%"/>'
    + '</div>'
  );

  $('body').append(div);
  var w1 = $(div).innerWidth();
  var w2 = $('div', div).innerWidth();
  $(div).remove();

  return w1 - w2;
};

Код отсюда: https://github.com/LearnBoost/antiscroll/blob/master/antiscroll.js#L447.

Hengjie
источник
3
detectScrollbarWidthHeight: function() {
    var div = document.createElement("div");
    div.style.overflow = "scroll";
    div.style.visibility = "hidden";
    div.style.position = 'absolute';
    div.style.width = '100px';
    div.style.height = '100px';
    document.body.appendChild(div);

    return {
        width: div.offsetWidth - div.clientWidth,
        height: div.offsetHeight - div.clientHeight
    };
},

Протестировано в Chrome, FF, IE8, IE11.

Бен
источник
2

Это должно сработать, нет?

function getScrollbarWidth() {
  return (window.innerWidth - document.documentElement.clientWidth);
}
Александр
источник
2

Создайте пустую divи убедитесь, что она присутствует на всех страницах (т.е. поместив ее вheader шаблон).

Дайте ему этот стиль:

#scrollbar-helper {
    // Hide it beyond the borders of the browser
    position: absolute;
    top: -100%;

    // Make sure the scrollbar is always visible
    overflow: scroll;
}

Затем просто проверьте размер #scrollbar-helperс помощью Javascript:

var scrollbarWidth = document.getElementById('scrollbar-helper').offsetWidth;
var scrollbarHeight = document.getElementById('scrollbar-helper').offsetHeight;

Нет необходимости вычислять что - либо, так как это divвсегда будет иметь widthи heightиз scrollbar.

Единственным недостатком является то, что divв ваших шаблонах будет пустой текст. Но, с другой стороны, ваши файлы Javascript будут чище, так как это займет всего 1 или 2 строки кода.

Этот парень
источник
1
function getWindowScrollBarHeight() {
    let bodyStyle = window.getComputedStyle(document.body);
    let fullHeight = document.body.scrollHeight;
    let contentsHeight = document.body.getBoundingClientRect().height;
    let marginTop = parseInt(bodyStyle.getPropertyValue('margin-top'), 10);
    let marginBottom = parseInt(bodyStyle.getPropertyValue('margin-bottom'), 10);
    return fullHeight - contentHeight - marginTop - marginBottom;
  }
allenhwkim
источник
1
function getScrollBarWidth() {
    return window.innerWidth - document.documentElement.clientWidth;
}

Большая часть браузера использует 15px для ширины полосы прокрутки

Shadow Grimes
источник
0

С помощью jquery (проверено только в Firefox):

function getScrollBarHeight() {
    var jTest = $('<div style="display:none;width:50px;overflow: scroll"><div style="width:100px;"><br /><br /></div></div>');
    $('body').append(jTest);
    var h = jTest.innerHeight();
    jTest.css({
        overflow: 'auto',
        width: '200px'
    });
    var h2 = jTest.innerHeight();
    return h - h2;
}

function getScrollBarWidth() {
    var jTest = $('<div style="display:none;height:50px;overflow: scroll"><div style="height:100px;"></div></div>');
    $('body').append(jTest);
    var w = jTest.innerWidth();
    jTest.css({
        overflow: 'auto',
        height: '200px'
    });
    var w2 = jTest.innerWidth();
    return w - w2;
}

Но мне больше нравится ответ @ Стива.

вереск
источник
0

Это отличный ответ: https://stackoverflow.com/a/986977/5914609

Однако в моем случае это не сработало. И я часами искал решение.
Наконец, я вернулся к приведенному выше коду и добавил! Важно для каждого стиля. И это сработало.
Я не могу добавить комментарии ниже исходного ответа. Итак, вот исправление:

function getScrollBarWidth () {
  var inner = document.createElement('p');
  inner.style.width = "100% !important";
  inner.style.height = "200px !important";

  var outer = document.createElement('div');
  outer.style.position = "absolute !important";
  outer.style.top = "0px !important";
  outer.style.left = "0px !important";
  outer.style.visibility = "hidden !important";
  outer.style.width = "200px !important";
  outer.style.height = "150px !important";
  outer.style.overflow = "hidden !important";
  outer.appendChild (inner);

  document.body.appendChild (outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll !important';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild (outer);

  return (w1 - w2);
};
Макс Ветряков
источник
0

Это решение позволит вам найти ширину прокрутки браузера (ванильный JavaScript). Используя этот пример, вы можете получить scrollY width для любого элемента, включая те элементы, которые не должны иметь прокрутку в соответствии с вашей текущей концепцией дизайна:

getComputedScrollYWidth     (el)  {

  let displayCSSValue  ; // CSS value
  let overflowYCSSValue; // CSS value

  // SAVE current original STYLES values
  {
    displayCSSValue   = el.style.display;
    overflowYCSSValue = el.style.overflowY;
  }

  // SET TEMPORALLY styles values
  {
    el.style.display   = 'block';
    el.style.overflowY = 'scroll';
  }

  // SAVE SCROLL WIDTH of the current browser.
  const scrollWidth = el.offsetWidth - el.clientWidth;

  // REPLACE temporally STYLES values by original
  {
    el.style.display   = displayCSSValue;
    el.style.overflowY = overflowYCSSValue;
  }

  return scrollWidth;
}
Евгений Мирошниченко
источник
0

Вот более краткое и простое для чтения решение, основанное на разнице ширины смещения:

function getScrollbarWidth(): number {

  // Creating invisible container
  const outer = document.createElement('div');
  outer.style.visibility = 'hidden';
  outer.style.overflow = 'scroll'; // forcing scrollbar to appear
  outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps
  document.body.appendChild(outer);

  // Creating inner element and placing it in the container
  const inner = document.createElement('div');
  outer.appendChild(inner);

  // Calculating difference between container's full width and the child width
  const scrollbarWidth = (outer.offsetWidth - inner.offsetWidth);

  // Removing temporary elements from the DOM
  outer.parentNode.removeChild(outer);

  return scrollbarWidth;

}

Смотрите JSFiddle .

Слава Фомин II
источник
0

Уже закодированы в моей библиотеке, так что вот оно:

var vScrollWidth = window.screen.width - window.document.documentElement.clientWidth;

Я должен отметить, что jQuery $(window).width()также может быть использован вместо window.document.documentElement.clientWidth.

Это не работает, если вы открываете инструменты разработчика в Firefox справа, но преодолевает это, если окно разработчика открывается внизу!

window.screenподдерживается quirksmode.org !

Радоваться, веселиться!

Centurian
источник
0

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

// Create the measurement node
var scrollDiv = document.createElement("div");
scrollDiv.className = "scrollbar-measure";
document.body.appendChild(scrollDiv);

// Get the scrollbar width
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
console.info(scrollbarWidth); // Mac:  15

// Delete the DIV 
document.body.removeChild(scrollDiv);
.scrollbar-measure {
	width: 100px;
	height: 100px;
	overflow: scroll;
	position: absolute;
	top: -9999px;
}

Goga
источник