如何获得浏览器视口尺寸?


788

我想为访问者提供观看高质量图像的能力,有什么方法可以检测到窗口大小吗?

或者更好的是,使用JavaScript的浏览器的视口大小?在此处查看绿色区域:


10
我要做的是,通常将html元素设置为100%高度并获取其高度。简单的作品随处可见。
穆罕默德·乌默

1
@MuhammadUmer好抓到!如果您对获取尺寸感到沮丧(并且在没有jQuery的手机上),则可以getComputedStyle使用扩展html标签。
2014年

另外,您可以使用W库,该库处理跨浏览器的视口检测;)
pyrsmk

Answers:


1326

跨浏览器 @media (width)@media (height)价值观 

const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);

window.innerWidth.innerHeight

  • 获取CSS视口 @media (width)@media (height)其中包括滚动条
  • initial-scale和缩放变化可能导致移动值错误地缩小到PPK称为可视视口@media值,并且小于该值
  • 缩放可能会由于本机舍入而导致值偏离1px
  • undefined 在IE8中

document.documentElement.clientWidth.clientHeight

资源资源


4
@ 01100001替换$verge。如果您想集成到jQuery中,请这样做jQuery.extend(verge)。请参阅:verge.airve.com/#static
ryanve

4
只是想提一下,在IE8(也许还有其他)中,必须<!DOCTYPE html>在页面顶部具有,才能使代码正常工作。
Tzury Bar Yochay

6
我对移动设备上的clientWidth / Height不满意,真的是Tripleodeon.com/wp-content/uploads/2011/12/table.html

24
除非我缺少任何东西,否则这个答案是错误的。至少在Chrome中,document.documentElement.clientHeight返回页面高度,而window.innerHeight返回视口高度。很大的区别。
Nate

2
不同的屏幕尺寸变量/解决方案实时测试:ryanve.com/lab/dimensions
Alex Pandrea

106

jQuery维度函数

$(window).width()$(window).height()


60
@allyourcode,不可能,jQuery是所有人的答案
Xeoncross 2011年

21
这不会获得视口的大小,但是会获得整体文档的大小。尝试一下。
亚历杭德罗·加西亚·伊格莱西亚斯

2
对于浏览器,其附加工具栏显示为具有固定位置的HTML,此解决方案不起作用,特别是如果要在代码的顶部位置和百分比中使用。
Adib Aroui 2014年

7
@AlejandroIglesias:不,我只是在此SO页面上对其进行了测试。$(window).height();返回536,而$("html").height();返回10599
Flimm,2016年

2
警告这些尺寸不包括滚动条(滚动条在不同的浏览器和平台中具有不同的大小),因此它们将与CSS媒体查询不匹配,但其他答案可以解决此问题。
Spencer O'Reilly

75

您可以使用window.innerWidthwindow.innerHeight属性。

内部高度与外部高度


29
即使在IE +1中对于图:D也不起作用。对于这样的问题,如果没有更多这些,应该是犯罪。
allyourcode

8
document.documentElement.clientWidthwindow.innerWidth
ryanve'1

6
@ryanve如果用“更准确”来表示“甚至不会远程执行相同的事情”,那么是的:P
装箱

Firefox Beta?那是属于博物馆的东西。
德里克·朕会功夫

@boxed在移动Safari中,document.documentElement.clientWidth给我视口宽度,而window.innerWidth给我文档宽度。是的,就是这样。
约翰

33

如果您不使用jQuery,它将变得很丑陋。这是一个适用于所有新浏览器的代码段。在IE的Quirks模式和标准模式下,行为是不同的。这样就好了。

var elem = (document.compatMode === "CSS1Compat") ? 
    document.documentElement :
    document.body;

var height = elem.clientHeight;
var width = elem.clientWidth;

8
这不是给您页面的高度,而不是视口的高度吗?该页面似乎表明了这一点:developer.mozilla.org/en/DOM/element.clientHeight
allyourcode 2009年

4
您正在使用clientHeight的上document.documentElement元素,这将给你的视口大小。要获取文档大小,您需要执行document.body.clientHeight。正如Chetan所解释的,这种行为适用于现代浏览器。这很容易测试。只需打开控制台并document.documentElement.clientHeight在几个打开的选项卡上键入即可。
Gajus 2014年

13

我知道这是可以接受的答案,但是我遇到了一种情况 clientWidth无法正常工作的情况,因为iPhone(至少是我的)返回了980,而不是320,所以我用了window.screen.width。我在现有网站上工作,变得“反应灵敏”,需要强制较大的浏览器使用其他元视图。

希望这对某人有帮助,可能并不完美,但可以在我在iOs和Android上进行的测试中使用。

//sweet hack to set meta viewport for desktop sites squeezing down to mobile that are big and have a fixed width 
  //first see if they have window.screen.width avail
  (function() {
    if (window.screen.width)
    {
      var setViewport = {
        //smaller devices
        phone: 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no',
        //bigger ones, be sure to set width to the needed and likely hardcoded width of your site at large breakpoints  
        other: 'width=1045,user-scalable=yes',
        //current browser width
        widthDevice: window.screen.width,
        //your css breakpoint for mobile, etc. non-mobile first
        widthMin: 560,
        //add the tag based on above vars and environment 
        setMeta: function () {
          var params = (this.widthDevice <= this.widthMin) ? this.phone : this.other; 
          var head = document.getElementsByTagName("head")[0];
          var viewport = document.createElement('meta');
          viewport.setAttribute('name','viewport');
          viewport.setAttribute('content',params);
          head.appendChild(viewport);
        }
      }
      //call it 
      setViewport.setMeta();
    }
  }).call(this);

13

我看了一下,发现了一种跨浏览器的方式:

function myFunction(){
  if(window.innerWidth !== undefined && window.innerHeight !== undefined) { 
    var w = window.innerWidth;
    var h = window.innerHeight;
  } else {  
    var w = document.documentElement.clientWidth;
    var h = document.documentElement.clientHeight;
  }
  var txt = "Page size: width=" + w + ", height=" + h;
  document.getElementById("demo").innerHTML = txt;
}
<!DOCTYPE html>
<html>
  <body onresize="myFunction()" onload="myFunction()">
   <p>
    Try to resize the page.
   </p>
   <p id="demo">
    &nbsp;
   </p>
  </body>
</html>


请注意,stackoverflow在代码段周围使用iframe会弄乱结果
Miller

11

我可以在JavaScript中找到一个明确的答案:第6版,由O'Reilly撰写的《权威指南》,第1页。391:

该解决方案甚至可以在Quirks模式下工作,而ryanve和ScottEvernden当前的解决方案则不行。

function getViewportSize(w) {

    // Use the specified window or the current window if no argument
    w = w || window;

    // This works for all browsers except IE8 and before
    if (w.innerWidth != null) return { w: w.innerWidth, h: w.innerHeight };

    // For IE (or any browser) in Standards mode
    var d = w.document;
    if (document.compatMode == "CSS1Compat")
        return { w: d.documentElement.clientWidth,
           h: d.documentElement.clientHeight };

    // For browsers in Quirks mode
    return { w: d.body.clientWidth, h: d.body.clientHeight };

}

除了事实,我不知道为什么行if (document.compatMode == "CSS1Compat")if (d.compatMode == "CSS1Compat"),一切都看起来不错。


您是在谈论Retina显示器还是Landscape或Portrait或meta视口标签?您不是像snowdragonledhk.com/…那样表示虚拟像素吗?
极性2014年

1)当谈论高DPI显示器时,我的意思是在这里解释虚拟像素:stackoverflow.com/a/14325619/139361。每个iPhone屏幕的宽度均为320个虚拟像素。2)我说:a)documentElement.clientWidth对iOS上的设备方向更改不响应。b)显示物理像素数(实际上无用),而不是虚拟像素
2014年

11

如果您正在寻找能够在mobile上以虚拟像素提供正确值的非jQuery解决方案,并且您认为简单window.innerHeightdocument.documentElement.clientHeight可以解决您的问题,请首先研究此链接: https //tripleodeon.com/assets/2011/12/ table.html

开发人员已进行了良好的测试,揭示了该问题:您可以为Android / iOS,横向/纵向,正常/高密度显示器获得意外的值。

我当前的答案还不是灵丹妙药(// todo),而是警告那些即将从该线程中将给定解决方案快速复制粘贴到生产代码中的人。

我一直在寻找移动设备上虚拟像素的页面宽度,但发现唯一有效的代码是(出乎意料!)window.outerWidth。稍后,我将在有空的时候检查此表以获取给出正确解决方案的解决方案,该解决方案可提供高度(导航栏除外)。




6

符合W3C标准的解决方案是创建一个透明的div(例如,使用JavaScript动态创建),将其宽度和高度设置为100vw / 100vh(视口单位),然后获取其offsetWidth和offsetHeight。之后,可以再次删除该元素。这在较旧的浏览器中将不起作用,因为视口单位是相对较新的,但是如果您不在乎它们,而只是在乎(即将成为)标准,那么您绝对可以这样:

var objNode = document.createElement("div");
objNode.style.width  = "100vw";
objNode.style.height = "100vh";
document.body.appendChild(objNode);
var intViewportWidth  = objNode.offsetWidth;
var intViewportHeight = objNode.offsetHeight;
document.body.removeChild(objNode);

当然,您也可以设置objNode.style.position =“ fixed”,然后使用100%作为宽度/高度-这应该具有相同的效果,并在一定程度上提高兼容性。同样,将位置设置为fixed可能通常是个好主意,因为否则div将是不可见的,但会占用一些空间,这将导致滚动条出现等。


不幸的是,现实完全摧毁了您的“ W3C标准解决方案”:1)caniuse.com/viewport-units,2caniuse.com/#feat=css-fixed。开发人员需要的是有效的解决方案,而不是“理论上应该有效”的解决方案。
2014年

如果我们可以依靠这些标准,那么我们甚至不需要所有这些跨浏览器解决方案。依赖规范的解决方案不是解决方案。
德里克·朕会功夫2014年

3

这是我做的方法,我在IE 8-> 10,FF 35,Chrome 40中尝试过,它将在所有现代浏览器(定义window.innerWidth)和IE 8(无窗口)中都非常流畅。 innerWidth)以及任何问题(例如由于溢出而闪烁:“隐藏”)都可以顺利运行,请进行报告。我对视口高度不真正感兴趣,因为我做了此功能只是为了解决一些响应工具,但它可能已实现。希望能有所帮助,我感谢您的评论和建议。

function viewportWidth () {
  if (window.innerWidth) return window.innerWidth;
  var
  doc = document,
  html = doc && doc.documentElement,
  body = doc && (doc.body || doc.getElementsByTagName("body")[0]),
  getWidth = function (elm) {
    if (!elm) return 0;
    var setOverflow = function (style, value) {
      var oldValue = style.overflow;
      style.overflow = value;
      return oldValue || "";
    }, style = elm.style, oldValue = setOverflow(style, "hidden"), width = elm.clientWidth || 0;
    setOverflow(style, oldValue);
    return width;
  };
  return Math.max(
    getWidth(html),
    getWidth(body)
  );
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.