Comment puis-je obtenir les tailles de la barre de défilement du navigateur?

165

Comment puis-je déterminer la hauteur d'une barre de défilement horizontale ou la largeur d'une barre verticale en JavaScript?

glmxndr
la source
2
Voici un extrait de code de l'auteur du plugin JQuery Dimension. github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/… peut-être tard pour donner cette solution, mais cela me semble meilleur, IMO.
Yanick Rochon
Jetez un œil à cette solution: davidwalsh.name/detect-scrollbar-width
GibboK
@GibboK - cette solution échoue - le offsetWidth == clientWidth donc c'est toujours zéro. Ceci est testé dans Edge IE && Chrome.
beauXjames
1
@beauXjames bizarre ça marche pour moi sur FF
GibboK
Cette question se pose dans la situation où la barre de défilement est au mauvais endroit (quelque part au milieu de l'écran). Dans cette situation, vous ne souhaitez probablement pas afficher de barre de défilement. Dans la plupart des cas, j'ai trouvé qu'iScroll était la solution neutre en matière de conception parfaite pour la situation: iscrolljs.com
JoostS

Réponses:

140

Du blog Alexandre Gomes je ne l'ai pas essayé. Dites-moi si cela marche pour vous.

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
la source
2
L'idée est géniale, je crée définitivement une classe MooTools basée sur cela.
Ryan Florence
Ouais, j'ai le même résultat Google. :) J'essaie de vous tenir informé.
glmxndr
si vous changez votre thème en un thème avec des barres de défilement de tailles différentes, quel est l'écart calculé par rapport au réel?
Matthew Vines
1
voir ici pour référence croisée: stackoverflow.com/questions/3417139/…
Yanick Rochon
6
Renvoie des valeurs différentes avec un zoom de page différent. Win7, Opera, FF.
Kolyunya
79

En utilisant jQuery, vous pouvez raccourcir la réponse de Matthew Vines à:

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
la source
2
Merci, cette solution est très propre !!
jherax
4
Cette solution serait-elle vraiment plus propre si tout le code source de JQuery était copié avant? Parce que c'est à peu près ce que fait cette solution. Cette question n'a pas demandé de réponse dans JQuery, et il est parfaitement possible et efficace d'effectuer cette tâche sans l'utilisation d'une bibliothèque.
DaemonOfTheWest
5
Si vous utilisez déjà JQuery, le commentaire de Daemon n'est pas pertinent. Oui, ajouter JQuery juste pour faire cela serait absurde, mais pour ceux qui utilisent déjà JQuery dans leur projet, c'est une solution beaucoup plus `` simple '' que celle acceptée.
Tyler Dahle
25

C'est le seul script que j'ai trouvé, qui fonctionne dans les navigateurs 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;
};

Version réduite:

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

Et vous devez l'appeler lorsque le document est prêt ... alors

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

Testé le 28/03/2012 sur Windows 7 dans les dernières versions de FF, Chrome, IE et Safari et fonctionne à 100%.

source: http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth

Jan Šafránek
la source
13
width sera TOUJOURS === indéfini dans ce code. autant faire si (vrai) {...}
sstur
3
Correction: widthsera toujours === indéfini la première fois que la fonction est appelée. Lors des appels ultérieurs à la fonction widthest déjà définie, cette vérification empêche simplement les calculs d'être réexécutés inutilement.
MartinAnsty
17
@MartinAnsty Mais la variable [width] est déclarée à l' intérieur de la fonction, elle est donc recréée chaque fois que vous appelez la fonction.
MadSkunk
4
@MartinAnsty, si vous regardez la source , elle est déclarée dans la fermeture externe.
TheCloudlessSky
3
Juste pour renforcer le point soulevé par @sstur et @TheCloudlessSky, le code ci-dessus n'est pas le même que celui du plugin de Ben Alman, et il ne mettra pas en cache le résultat width, mais le recalculera à chaque fois. Cela fonctionne, mais c'est terriblement inefficace. Merci de rendre service au monde entier et d'utiliser à la place la version correcte du plugin d'Alman.
hashchange
24

si vous cherchez une opération simple, mélangez simplement dom js et jquery,

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

renvoie la taille de la barre de défilement de la page actuelle. (s'il est visible ou sinon retournera 0)

Beep.exe
la source
10
Cela échouera si la fenêtre n'a pas de barres de défilement (grand écran ou petite page / application)
Farid Nouri Neshat
1
c'est parfaitement ce que je voulais
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
la source
J'ai d'abord essayé la réponse acceptée, mais j'ai constaté que cela ne fonctionnait plus dans Firefox sous Windows 8. Passé à cette variante qui fait le travail à merveille.
Matijs
1
Code plus court, mais le navigateur doit redessiner la page entière, donc c'est très lent.
Adrian Maire
11

Pour moi, le moyen le plus utile était

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

avec JavaScript vanille.

entrez la description de l'image ici

Andrés Moreno
la source
Merci @ stephen-kendy. Une salutation.
Andrés Moreno
3
Juste ce dont j'avais besoin. Une suggestion: le deuxième terme peut être remplacé par document.documentElement.clientWidth. documentElementexprime plus clairement et proprement l'intention d'obtenir l' <html>élément.
Jan Miksovsky
9

J'ai trouvé une solution simple qui fonctionne pour les éléments à l'intérieur de la page, au lieu de la page elle-même: $('#element')[0].offsetHeight - $('#element')[0].clientHeight

Cela renvoie la hauteur de la barre de défilement de l'axe x.

Memet Olsen
la source
Elle est bonne!! Vous avez fait ma journée :) Cela fonctionne également avec ".offsetWidth" et ".clientWidth" pour les barres de défilement de l'axe y.
Polosson du
1
Cela ne semble pas entièrement fiable, malheureusement, du moins pour les largeurs. .clientWidth semble inclure la moitié de la largeur de la barre de défilement dans FireFox et Chrome sous Linux.
Michael Scheper
6

Du blog de David Walsh :

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

Me donne 17 sur mon site Web, 14 ici sur Stackoverflow.

mpen
la source
4

Si vous avez déjà un élément avec des barres de défilement, utilisez:

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

S'il n'y a pas d'horzintscrollbar, la fonction sera relancée 0

mons droïde
la source
C'est la meilleure réponse à ce jour. KISS règles tout
MarcD
4

Vous pouvez déterminer la windowbarre de défilement avec documentcomme ci-dessous en utilisant jquery + javascript:

var scrollbarWidth = ($(document).width() - window.innerWidth);
console.info("Window Scroll Bar Width=" + scrollbarWidth );
Bhuwan Prasad Upadhyay
la source
Notez que innerWidth est pour IE9 +. Sinon excellente solution.
Pål Thingbø
3

Le chemin Antiscroll.js cela fonctionne dans son code est:

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

Le code vient d'ici: https://github.com/LearnBoost/antiscroll/blob/master/antiscroll.js#L447

Hengjie
la source
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
    };
},

Testé dans Chrome, FF, IE8, IE11.

Ben
la source
2

Cela devrait faire l'affaire, non?

function getScrollbarWidth() {
  return (window.innerWidth - document.documentElement.clientWidth);
}
Alexandre
la source
2

Créez un vide divet assurez-vous qu'il est présent sur toutes les pages (c'est-à-dire en le mettant dans leheader modèle).

Donnez-lui ce style:

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

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

Ensuite, vérifiez simplement la taille de #scrollbar-helperavec Javascript:

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

Pas besoin de calculer quoi que ce soit, car cela divaura toujours le widthet heightduscrollbar .

Le seul inconvénient est qu'il y aura un vide divdans vos templates .. Mais d'un autre côté, vos fichiers Javascript seront plus propres, car cela ne prend que 1 ou 2 lignes de code.

Ce mec
la source
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
la source
1
function getScrollBarWidth() {
    return window.innerWidth - document.documentElement.clientWidth;
}

La plupart des navigateurs utilisent 15px pour la largeur de la barre de défilement

Grimes de l'ombre
la source
0

Avec jquery (testé uniquement sous 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;
}

Mais j'aime mieux la réponse de @ Steve.

lingue
la source
0

C'est une excellente réponse: https://stackoverflow.com/a/986977/5914609

Cependant, dans mon cas, cela n'a pas fonctionné. Et j'ai passé des heures à chercher la solution.
Enfin, je suis revenu au code ci-dessus et j'ai ajouté! Important à chaque style. Et ça a marché.
Je ne peux pas ajouter de commentaires sous la réponse originale. Voici donc le correctif:

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
la source
0

Cette décision de hack de la vie vous donnera l'opportunité de trouver la largeur de défilement du navigateur (JavaScript vanilla). En utilisant cet exemple, vous pouvez obtenir la largeur de scrollY sur n'importe quel élément, y compris les éléments qui ne devraient pas avoir de défilement en fonction de votre conception actuelle,:

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
la source
0

Voici la solution la plus concise et la plus facile à lire basée sur la différence de largeur de décalage:

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;

}

Voir le JSFiddle .

Slava Fomin II
la source
0

Déjà codé dans ma bibliothèque alors le voici:

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

Je dois mentionner que jQuery $(window).width()peut également être utilisé à la place de window.document.documentElement.clientWidth.

Cela ne fonctionne pas si vous ouvrez les outils de développement dans Firefox sur la droite, mais cela le surmonte si la fenêtre de développement est ouverte en bas!

window.screenest pris en charge quirksmode.org !

S'amuser!

centurien
la source
0

Cela semble fonctionner, mais il existe peut-être une solution plus simple qui fonctionne dans tous les navigateurs?

// 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
la source