ฉันจะรับขนาดแถบเลื่อนของเบราว์เซอร์ได้อย่างไร


164

ฉันจะกำหนดความสูงของแถบเลื่อนแนวนอนหรือความกว้างของแถบเลื่อนแนวตั้งใน JavaScript ได้อย่างไร


2
นี่คือตัวอย่างข้อมูลจากผู้แต่งปลั๊กอิน JQuery Dimension github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/ ......อาจจะช้าที่จะแก้ปัญหานี้ แต่ดูเหมือนว่า IMO ที่ดีกว่าสำหรับฉัน
Yanick Rochon

ดูวิธีแก้ปัญหานี้: davidwalsh.name/detect-scrollbar-width
GibboK

@GibboK - โซลูชั่นนั้นล้มเหลว - offsetWidth == clientWidth ดังนั้นจึงเป็นศูนย์เสมอ นี่คือการทดสอบในขอบ IE && Chrome
beauXjames

1
@beauXjames แปลกมันใช้ได้กับฉันใน FF
GibboK

คำถามนี้เกิดขึ้นในสถานการณ์ที่แถบเลื่อนอยู่ในตำแหน่งที่ไม่ถูกต้อง (อยู่ตรงกลางของหน้าจอ) ในสถานการณ์นี้คุณอาจไม่ต้องการแสดงแถบเลื่อน ในกรณีส่วนใหญ่ฉันพบว่า iScroll เป็นโซลูชันที่เป็นกลางในการออกแบบที่สมบูรณ์แบบสำหรับสถานการณ์: iscrolljs.com
JoostS

คำตอบ:


139

จากบล็อก Alexandre Gomes ฉันยังไม่ได้ลอง แจ้งให้เราทราบว่าเหมาะกับคุณหรือไม่

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 ตามนี้
Ryan Florence

ใช่ฉันได้รับผล google เดียวกัน :) ฉันพยายามและแจ้งให้คุณทราบ
glmxndr

หากคุณเปลี่ยนชุดรูปแบบของคุณเป็นหนึ่งเดียวกับแถบเลื่อนขนาดต่าง ๆ ความเบี่ยงเบนในการคำนวณเป็นจริงคืออะไร
แมทธิวเถา

1
ดูที่นี่สำหรับการอ้างอิงโยง: stackoverflow.com/questions/3417139/…
Yanick Rochon

6
ส่งคืนค่าที่ต่างกันด้วยการซูมหน้าแตกต่างกัน Win7, Opera, FF
Kolyunya

79

เมื่อใช้ jQuery คุณสามารถย่อ 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;
};

2
ขอบคุณวิธีนี้สะอาดมาก !!
jherax

4
โซลูชันนี้จะรู้สึกสะอาดกว่านี้หรือไม่หากซอร์สโค้ดทั้งหมดสำหรับ JQuery ถูกคัดลอกวางไว้ก่อนหน้า เพราะนั่นเป็นสิ่งที่โซลูชันนี้ทำอยู่ คำถามนี้ไม่ได้ขอคำตอบใน JQuery และเป็นไปได้อย่างสมบูรณ์และมีประสิทธิภาพในการทำงานนี้โดยไม่ต้องใช้ห้องสมุด
DaemonOfTheWest

5
หากคุณใช้ JQuery อยู่แล้วความคิดเห็นของ Daemon นั้นไม่เกี่ยวข้อง ใช่เพื่อเพิ่ม JQuery เพียงเพื่อจะเป็นเรื่องไร้สาระ แต่สำหรับผู้ที่ใช้ JQuery ในโครงการของพวกเขาแล้วนี่เป็นวิธีการแก้ปัญหาที่ 'ง่ายกว่า' มากกว่าวิธีที่ได้รับการยอมรับ
Tyler Dahle

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จะเสมอ === ไม่ได้กำหนดครั้งแรกเวลาฟังก์ชั่นที่เรียกว่า เมื่อโทรไปที่ฟังก์ชั่นwidthมีการตั้งค่าการตรวจสอบนั้นจะป้องกันไม่ให้การคำนวณถูกเรียกใช้อีกครั้งโดยไม่จำเป็น
MartinAnsty

17
@MartinAnsty แต่มีการประกาศตัวแปร [width] ภายในฟังก์ชันดังนั้นจึงสร้างขึ้นใหม่ทุกครั้งที่คุณเรียกใช้ฟังก์ชัน
MadSkunk

4
@MartinAnsty ถ้าคุณดูแหล่งที่มามันถูกประกาศในการปิดด้านนอก
TheCloudlessSky

3
เพียงเพื่อเสริมจุดที่ @sstur และ @TheCloudlessSky รหัสข้างต้นไม่เหมือนกับที่อยู่ในปลั๊กอินของ Ben Alman และมันจะไม่แคชผลลัพธ์widthแต่จะทำการคำนวณใหม่ทุกครั้ง มันใช้งานได้ แต่มันไม่มีประสิทธิภาพมากนัก โปรดทำให้โลกเป็นที่โปรดปรานและใช้รุ่นที่ถูกต้องในปลั๊กอินของ Alman แทน
hashchange

24

หากคุณกำลังมองหาการดำเนินการที่เรียบง่ายเพียงผสม dom js และ jquery ธรรมดา

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

ส่งคืนขนาดของแถบเลื่อนหน้าปัจจุบัน (หากมองเห็นได้มิฉะนั้นจะส่งคืน 0)


10
สิ่งนี้จะล้มเหลวในกรณีที่หน้าต่างไม่มีแถบเลื่อน (จอใหญ่หรือหน้าเล็ก / แอป)
Farid Nouri Neshat

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
รหัสสั้นกว่า แต่เบราว์เซอร์จะต้องวาดทั้งหน้าใหม่ดังนั้นจึงช้ามาก
Adrian Maire

11

สำหรับฉันแล้ววิธีที่มีประโยชน์ที่สุดคือ

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

ด้วยวานิลลา JavaScript

ป้อนคำอธิบายรูปภาพที่นี่


ขอบคุณ @ stephen-kendy คำทักทาย
Andrés Moreno

3
สิ่งที่ฉันต้องการ หนึ่งคำแนะนำ: document.documentElement.clientWidthในระยะที่สองสามารถถูกแทนที่ด้วย documentElementแสดงความตั้งใจและชัดเจนในการรับ<html>องค์ประกอบให้ชัดเจนยิ่งขึ้น
Jan Miksovsky

9

ฉันพบโซลูชันง่าย ๆ ที่ใช้งานได้กับองค์ประกอบภายในหน้าแทนที่จะเป็นหน้าตัวเอง: $('#element')[0].offsetHeight - $('#element')[0].clientHeight

สิ่งนี้จะคืนความสูงของแถบเลื่อนแกน x


เยี่ยมมาก !! คุณทำให้วันของฉัน :) มันทำงานได้ดีกับ ".setsetWidth" และ ".clientWidth" สำหรับแถบเลื่อนแกน y
Polosson

1
ดูเหมือนจะไม่น่าเชื่อถืออย่างสิ้นเชิง แต่น่าเสียดายที่อย่างน้อยก็สำหรับความกว้าง .clientWidth ดูเหมือนจะรวมความกว้างของแถบเลื่อนครึ่งหนึ่งในทั้ง FireFox และ Chrome ภายใต้ Linux
Michael Scheper

6

จากบล็อกของ 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;
}

ให้ฉัน 17 กับเว็บไซต์ของฉัน 14 ที่นี่บน Stackoverflow


4

หากคุณมีองค์ประกอบที่มีแถบเลื่อนใช้อยู่:

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

ถ้าไม่มี horzintscrollbar ปรากฏขึ้นฟังก์ชันจะทำการ retun 0


นี่คือคำตอบที่ดีที่สุด จูบกฎทั้งหมด
MarcD

4

คุณสามารถกำหนดwindowแถบเลื่อนด้วยdocumentด้านล่างโดยใช้ jquery + javascript:

var scrollbarWidth = ($(document).width() - window.innerWidth);
console.info("Window Scroll Bar Width=" + scrollbarWidth );

โปรดทราบว่า InnerWidth สำหรับ IE9 + ทางออกที่ดีเป็นอย่างอื่น
PålThingbø

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


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

สร้างที่ว่างเปล่า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และของheightscrollbar

ข้อเสียเพียงอย่างเดียวคือ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;
  }

1
function getScrollBarWidth() {
    return window.innerWidth - document.documentElement.clientWidth;
}

เบราว์เซอร์ส่วนใหญ่ใช้ 15px สำหรับความกว้างของแถบเลื่อน


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

แต่ฉันชอบคำตอบของ @ Steve ดีกว่า


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

การตัดสินใจแฮ็คชีวิตนี้จะให้โอกาสคุณในการค้นหาความกว้าง scrollY ของเบราว์เซอร์ (JavaScript วานิลลา) ใช้ตัวอย่างนี้คุณสามารถรับความกว้าง scrollY ในองค์ประกอบใด ๆรวมถึงองค์ประกอบที่ไม่ควรมีการเลื่อนตามแนวคิดการออกแบบปัจจุบันของคุณ:

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


0

เขียนรหัสแล้วในห้องสมุดของฉันดังนั้นนี่คือ:

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

ฉันควรพูดถึงว่า jQuery $(window).width()สามารถใช้แทนได้window.document.documentElement.clientWidthนอกจากนี้ยังสามารถนำมาใช้แทน

มันไม่ทำงานหากคุณเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ใน Firefox ด้านขวา แต่มันจะเอาชนะได้หากหน้าต่าง devs เปิดที่ด้านล่าง!

window.screenได้รับการสนับสนุนquirksmode.org !

มีความสุข!


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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.