Jak mogę sprawdzić rozmiary paska przewijania w przeglądarce?

164

Jak określić wysokość poziomego paska przewijania lub szerokość pionowego w JavaScript?

glmxndr
źródło
2
Oto fragment od autora wtyczki JQuery Dimension. github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/ ... może spóźniłem się na to rozwiązanie, ale wydaje mi się, że jest to lepsze rozwiązanie, IMO.
Yanick Rochon
Spójrz na to rozwiązanie: davidwalsh.name/detect-scrollbar-width
GibboK
@GibboK - to rozwiązanie zawodzi - offsetWidth == clientWidth, więc zawsze wynosi zero. Jest to testowane w Edge IE i Chrome.
beauXjames
1
@beauXjames dziwne, że działa na mnie na FF
GibboK,
To pytanie pojawia się w sytuacji, gdy pasek przewijania znajduje się w złym miejscu (gdzieś pośrodku ekranu). W tej sytuacji prawdopodobnie nie chcesz wyświetlać paska przewijania. W większości przypadków iScroll jest dla mnie idealnym rozwiązaniem neutralnym pod względem projektowym w tej sytuacji: iscrolljs.com
JoostS

Odpowiedzi:

139

Z bloga Alexandre Gomes nie próbowałem tego. Daj mi znać, jeśli to zadziała.

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);
};
Matthew Vines
źródło
2
Pomysł jest genialny, zdecydowanie na tej podstawie tworzę klasę MooTools.
Ryan Florence
Tak, mam ten sam wynik w Google. :) Próbuję i informuję Cię na bieżąco.
glmxndr
jeśli zmienisz motyw na taki, który ma paski przewijania o różnych rozmiarach, jakie jest odchylenie obliczane na rzeczywiste?
Matthew Vines,
1
zobacz tutaj dla odniesienia: stackoverflow.com/questions/3417139/…
Yanick Rochon
6
Zwraca różne wartości przy różnym powiększeniu strony. Win7, Opera, FF.
Kolyunya
79

Korzystając z jQuery, możesz skrócić odpowiedź Matthew Vinesa do:

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;
};
Joshua Bambrick
źródło
2
Dzięki, to rozwiązanie jest bardzo czyste !!
jherax
4
Czy to rozwiązanie naprawdę wydawałoby się czystsze, gdyby cały kod źródłowy JQuery został wcześniej skopiowany? Ponieważ to właśnie robi to rozwiązanie. To pytanie nie wymagało odpowiedzi w JQuery, a wykonanie tego zadania bez użycia biblioteki jest całkowicie możliwe i wydajne.
DaemonOfTheWest,
5
Jeśli już używasz JQuery, komentarz Daemona jest nieistotny. Tak, dodanie JQuery tylko po to, by to zrobić, byłoby nonsensem, ale dla tych, którzy już używają JQuery w swoim projekcie, jest to znacznie „prostsze” rozwiązanie niż przyjęte.
Tyler Dahle,
25

To jest tylko skrypt, który znalazłem, który działa w przeglądarkach 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;
};

Zminimalizowana wersja:

$.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};

I musisz to wywołać, gdy dokument będzie gotowy ... tak

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

Testowane 2012-03-28 na Windows 7 w najnowszych wersjach FF, Chrome, IE i Safari iw 100% sprawne.

źródło: http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth

Jan Šafránek
źródło
13
width będzie ZAWSZE === niezdefiniowana w tym kodzie. równie dobrze mógłby zrobić, gdyby (prawda) {...}
sstur
3
Korekta: widthbędzie zawsze === undefined pierwszym razem, gdy funkcja jest wywoływana. Przy kolejnych wywołaniach funkcja widthjest już ustawiona, to sprawdzenie po prostu zapobiega niepotrzebnemu ponownemu wykonywaniu obliczeń.
MartinAnsty
17
@MartinAnsty Ale zmienna [width] jest zadeklarowana wewnątrz funkcji, dlatego jest odtwarzana za każdym razem, gdy wywołujesz funkcję.
MadSkunk
4
@MartinAnsty, jeśli spojrzysz na źródło , zostanie ono zadeklarowane w zewnętrznym zamknięciu.
TheCloudlessSky
3
Aby wzmocnić argument @sstur i @TheCloudlessSky, powyższy kod nie jest tym samym, co ten we wtyczce Bena Almana i nie zapisze wyniku w pamięci podręcznej width, ale za każdym razem ponownie go obliczy. Działa, ale jest strasznie nieefektywny. Zrób światu przysługę i zamiast tego użyj poprawnej wersji wtyczki Almana.
hashchange
24

jeśli szukasz prostej operacji, po prostu wymieszaj zwykłe dom js i jquery,

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

zwraca rozmiar paska przewijania bieżącej strony. (jeśli jest widoczny lub zwróci 0)

Beep.exe
źródło
10
To się nie powiedzie w przypadku, gdy okno nie ma pasków przewijania (duży monitor lub mała strona / aplikacja)
Farid Nouri Neshat
1
właśnie tego chciałem
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; 
} 
Josh Stodola
źródło
Najpierw wypróbowałem zaakceptowaną odpowiedź, ale okazało się, że nie działa ona już w Firefoksie w systemie Windows 8. Przełączono na ten wariant, który doskonale spełnia swoje zadanie.
Matijs
1
Krótszy kod, ale przeglądarka musi przerysować całą stronę, więc działa bardzo wolno.
Adrian Maire
11

Dla mnie najbardziej przydatnym sposobem był

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

z waniliowym JavaScriptem.

wprowadź opis obrazu tutaj

Andrés Moreno
źródło
Dzięki @ stephen-kendy. Pozdrowienie.
Andrés Moreno
3
Dokładnie to, czego potrzebowałem. Jedna sugestia: drugi termin można zastąpić document.documentElement.clientWidth. documentElementjaśniej i wyraźniej wyraża zamiar uzyskania <html>elementu.
Jan Miksovsky
9

Znalazłem proste rozwiązanie, które działa w przypadku elementów wewnątrz strony, zamiast samej strony: $('#element')[0].offsetHeight - $('#element')[0].clientHeight

Zwraca wysokość paska przewijania osi X.

Memet Olsen
źródło
Świetny !! Zrobiłeś mój dzień :) Działa również z ".offsetWidth" i ".clientWidth" dla pasków przewijania osi Y.
Polosson
1
Nie wydaje się, niestety, całkowicie niezawodny, przynajmniej w przypadku szerokości. .clientWidth wydaje się obejmować połowę szerokości paska przewijania w FireFox i Chrome pod Linuksem.
Michael Scheper
6

Z bloga Davida Walsha :

// 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;
}

Daje mi 17 na mojej stronie internetowej, 14 tutaj na Stackoverflow.

mpen
źródło
4

Jeśli masz już element z paskiem przewijania, użyj:

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

Jeśli nie ma paska przewijania horzints, funkcja powróci do 0

mons droid
źródło
To najlepsza jak dotąd odpowiedź. KISS rządzi wszystkim
MarcD
4

Możesz określić windowpasek przewijania za pomocą documentjak poniżej za pomocą jquery + javascript:

var scrollbarWidth = ($(document).width() - window.innerWidth);
console.info("Window Scroll Bar Width=" + scrollbarWidth );
Bhuwan Prasad Upadhyay
źródło
Zauważ, że innerWidth dotyczy przeglądarki IE9 +. W przeciwnym razie świetne rozwiązanie.
Pål Thingbø
3

Sposób Antiscroll.jsw jego kodzie to:

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;
};

Kod pochodzi stąd: https://github.com/LearnBoost/antiscroll/blob/master/antiscroll.js#L447

Hengjie
źródło
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
    };
},

Przetestowano w Chrome, FF, IE8, IE11.

Ben
źródło
2

To powinno załatwić sprawę, prawda?

function getScrollbarWidth() {
  return (window.innerWidth - document.documentElement.clientWidth);
}
Alexander
źródło
2

Utwórz pusty divi upewnij się, że jest obecny na wszystkich stronach (np. Umieszczając go w headerszablonie).

Daj mu taką stylizację:

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

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

Następnie po prostu sprawdź rozmiar za #scrollbar-helperpomocą Javascript:

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

Nie musisz niczego obliczać, ponieważ divzawsze będzie to mieć widthand heightof scrollbar.

Jedynym minusem jest to, że divw twoich szablonach będzie pusty .. Ale z drugiej strony, twoje pliki Javascript będą czystsze, ponieważ zajmuje to tylko 1 lub 2 linie kodu.

Ten facet
źródło
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
źródło
1
function getScrollBarWidth() {
    return window.innerWidth - document.documentElement.clientWidth;
}

W większości przeglądarek szerokość paska przewijania wynosi 15 pikseli

Shadow Grimes
źródło
0

Z jQuery (testowane tylko w Firefoksie):

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;
}

Ale tak naprawdę bardziej podoba mi się odpowiedź @ Steve.

molwa
źródło
0

To świetna odpowiedź: https://stackoverflow.com/a/986977/5914609

Jednak w moim przypadku to nie zadziałało. I spędziłem godziny na poszukiwaniu rozwiązania.
Wreszcie wróciłem do powyższego kodu i dodałem! Ważne do każdego stylu. I zadziałało.
Nie mogę dodać komentarzy pod oryginalną odpowiedzią. Oto poprawka:

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);
};
Max Vetriakov
źródło
0

Ta życiowa decyzja da ci możliwość znalezienia szerokości scrollY przeglądarki (waniliowy JavaScript). Korzystając z tego przykładu, możesz uzyskać szerokość scrollY dowolnego elementu, w tym elementów, które nie powinny mieć scrollu zgodnie z twoją obecną koncepcją projektową:

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;
}
Evgeniy Miroshnichenko
źródło
0

Oto bardziej zwięzłe i łatwiejsze do odczytania rozwiązanie oparte na różnicy szerokości przesunięcia:

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;

}

Zobacz JSFiddle .

Slava Fomin II
źródło
0

Już zakodowane w mojej bibliotece, więc oto jest:

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

Powinienem wspomnieć, że $(window).width()zamiast niego można również użyć jQuery window.document.documentElement.clientWidth.

To nie działa, jeśli otworzysz narzędzia programistyczne w przeglądarce Firefox po prawej stronie, ale pokonuje to, jeśli okno deweloperów zostanie otwarte u dołu!

window.screenjest obsługiwany przez quirksmode.org !

Baw się dobrze!

centurian
źródło
0

Wydaje się, że działa, ale może istnieje prostsze rozwiązanie, które działa we wszystkich przeglądarkach?

// 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
źródło