JavaScript:获取窗口宽度减去滚动条宽度

9

好的,我以为这很简单,但结果并不是这样。我想我只是在我的HTML/CSS中弄错了什么,但是还是试一下。

我有一个基本页面,如下所示:

HTML

<!DOCTYPE html>
<html>
  <head>
    <link href='test2.css' rel="stylesheet" type="text/css" />
    <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
    <script src="test2.js"></script>
  </head>
  <body>
    <div id="scroll"></div>
  </body>
</html>

test2.css

* {
  padding: 0;
  margin: 0;
}

html, body {
  height: 100%;
  width: 100%;
}

#scroll {
  height: 100%;
  width: 100%;
  overflow: scroll;
  background-color: black;
}

test2.js

$(document).ready(function() {
  // my resolution is 1440x900
  alert('innerwidth should be 1425');
  // all of these return 1440
  alert('body innerwidth: ' + $('body').innerWidth());
  alert('document width: ' + $(document).width());
  alert('window width: ' + $(window).width());
  alert('scroll div innerwidth: ' + $('#scroll').innerWidth());
  alert('document.documentElement.clientWidth: ' + document.documentElement.clientWidth);
  alert('document.documentElement.scrollWidth: ' + document.documentElement.scrollWidth);
});

所以我在页面上只有一个元素……一个 div 占据整个屏幕,或者更确切地说,它应该占据整个屏幕,减去滚动条。现在,我一直在研究如何获取没有滚动条的页面宽度和高度,但不幸的是,它们都没有返回正确的值……这让我相信我在 HTML 或 CSS 上做错了什么。
我看了以下内容: jquery - how to get screen width without scrollbar? how to get the browser window size without the scroll bars 所以我需要一种方法来返回我的可视屏幕值,减去各自的滚动条值……所以对于我的宽度,我的值应该是 1425,因为滚动条的宽度为 15 像素。我认为这就是 innerWidth 的工作,但显然我错了?
有人能提供任何见解吗?(我正在运行 Firefox 24。)
编辑
为了提供一些背景,我有一个空白页面。我将逐个添加元素到此页面,并在计算这些元素的大小时需要使用页面的宽度。最终,此页面将不断增长,直到出现滚动条,这就是为什么我试图从一开始就强制出现滚动条,但显然这仍然没有任何作用。
编辑2
更有趣的是...如果我执行document.getElementById('scroll').clientWidth,我会得到正确的innerWidth,但如果我执行$('#scroll').width()或$('#scroll').innerWidth(),它们都返回最大分辨率...听起来像是jQuery的一个bug。

4个回答

3
我从别处得到了这个方法,如果我知道来源的话会给予致谢。这对我来说非常成功。在将html溢出设置为hidden时,我将结果添加为填充。
问题是滚动条是浏览器的特性而不是网页本身。应该动态地进行测量。带有滚动条和不带滚动条的测量将导致计算宽度差异。
找到了来源:http://www.fleegix.org/articles/2006/05/30/getting-the-scrollbar-width-in-pixels
scrollCompensate = function () {
    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);
}

var htmlpadding = scrollCompensate();

嗯,对于屏幕宽度这么简单的事情来说,这看起来有点复杂。 - incutonez
添加了一些更多的描述。看起来有点复杂,但实际上并不是。事实上这些步骤是必要的。我以前也曾苦恼过这个问题。有趣的是,在宽度测量中看到这些奇怪的结果.. :-) - Daniel
这里有更有趣的事情...如果我执行 document.getElementById('scroll').clientWidth,我会得到正确的 innerWidth,但是如果我执行 $('#scroll').width() 或者 $('#scroll').innerWidth(),它们都会返回最大分辨率...听起来像是 jQuery 的一个 bug。 - incutonez
我不确定它是否与边距或填充有关,就像我在启动CSS时进行重置以将它们设置为零一样。也许这也很有趣。请注意outerHeight(true) .. 在此处查看 - Daniel
嗯,但我的填充和边距被清零了。也许我只是不理解width/innerWidth?从那个表格的样子来看,width不应该包括padding、border或margin... innerWidth应该只包括paddiing。所以看起来它们没有被包括进去,但它们确实包括滚动条...这有点误导人。 - incutonez

3
正确答案在这篇被标记为已接受的帖子中: CSS媒体查询和JavaScript窗口宽度不匹配 以下是正确的代码:
function viewport() {
  var e = window, a = 'inner';
  if (!('innerWidth' in window )) {
    a = 'client';
    e = document.documentElement || document.body;
  }
  return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}

最佳答案在这里。非常有效! - Scottie
4
抱歉,在Chrome中(撰写时为v39版本),此方法无效 - 我仍然会包括滚动条的宽度。 - pospi

2

我发现了一个非常hacky的解决方案……在test2.js中我的警报之前添加以下内容,我可以得到正确的宽度:

var p = $('body').append('<p style="height: 100%; width: 100%;"></p>');
alert(p.width());
$('body').remove('p');

因此,所有的警报现在都有了正确的宽度。如果我用这种方式做,甚至不需要在CSS中使用overflow-y。不知道为什么这样就解决了...

真正的答案应该是保持HTML和CSS不变,然后使用document.getElementById('scroll').clientWidth。使用clientWidth可以得到可视区域减去滚动条宽度。


1
页面的正确宽度由$(document).width()给出。 你的问题在于你在div内使用了一个scroll (overflow: scroll)。 使用$(document).width()返回的值已经减去了scroll的可见宽度,但是如果在div中放置scroll,返回的值就不再相同。 由于scroll的宽度不是标准的,并且在系统和浏览器之间有所不同,因此很难解决这个问题。 我建议你删除div中的scroll,让浏览器默认地在body中管理它,然后你就可以得到正确的宽度了。

1
我对这个问题的困扰在于...假设我有一个空白页面,并且根据您的知识,在任何元素上都没有使用overflow:scroll。我使用页面的宽度来调整逐个添加的元素的大小,最终这个页面会增长到需要滚动条的地步。一旦滚动条出现,所有之前的元素大小都是错误的,所以现在我很无助。这样说您明白了吗? - incutonez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接