如何在JavaScript中获取屏幕,窗口和网页大小

16,923 阅读8分钟

浏览器的各种尺寸是javaScript中比较容易混淆的概念,下面我会在本文中解释这些概念并且通过具体示例告诉大家如何访问它们。各位客官看好叻🍵

屏幕

屏幕尺寸

屏幕尺寸是屏幕的宽度和高度:显示器或移动屏幕。window.screen是保存屏幕尺寸信息的对象。

  • screen.width:屏幕的宽。
  • screen.height:屏幕的高。

可用屏幕尺寸

可用的屏幕大小由活动屏幕的宽度和高度组成,没有操作系统工具栏。

  • screen.availWidth:可利用的宽,等于屏幕的宽。
  • screen.availHeight:可利用的高,等于屏幕的高减去 mac 顶部栏或 windows 底部栏。

屏幕距离

  • screenTop:浏览器窗口左上角到屏幕上边缘的距离。
  • screenLeft:浏览器窗口左上角到屏幕左边缘的距离。 Firefox 浏览器不支持上述属性,但是可以使用👇:
  • screenX:等于 screenLeft。
  • screenY:等于 screenTop。

附录

  1. chrome/Opera:保存的是浏览器窗口左上角相对于屏幕的距离
  • 全屏时四个值均为0
  1. Firefox/Safari:保存的是浏览器窗口左上角相对于屏幕的距离
  • 当浏览器窗口全屏化时指的是整个浏览器与屏幕左上角的距离,因为在全屏化的时候浏览器边缘8px的边框不显示,所以screenXscreenY为-8
  1. IE:保存的是浏览器窗口文档显示区域的左上角相对于屏幕左上角的位置。
  • 网页顶部到屏幕顶部的距离:window.screenTop(浏览器全屏为工具栏的高度)
  • 网页左边到屏幕左边的距离:window.screenLeft(浏览器全屏为0)
  1. ie9+
  • 浏览器窗口全屏化时screenXscreenY为-8
var leftPos = (typeof window.screenLeft=='number')?window.screenLeft:window.screenX;

window窗口

窗口外部尺寸

窗口的外部大小由整个浏览器窗口的宽度和高度组成,包含地址栏,选项卡栏和其他浏览器面板。

  • window.outerWidth:浏览器窗口的宽。
  • window.outerHeight:浏览器窗口的高。

1、 在Chrome和Opera中,当浏览器窗口全屏化时,outerWidthouterHeight指的是可以看到的浏览器部分所占据的空间。

2、在FireFox、Safari、IE9和IE10中,当浏览器窗口全屏化时,outerWidthouterHeight指的不仅是可以看到的浏览器所占据的空间,还包括其未显示部分。当浏览器窗口退出全屏化时,其四周会有8px的边框。而当浏览器窗口全屏化时,边框虽然未被显示,但仍然是计算在outerWidthouterHeight内。

3、IE7、8不支持。

窗口内部尺寸

窗口的内部大小(也称为视口大小)由显示网页的视口的宽度和高度组成,包含滚动条。

  • window.innerWidth:视口的宽。
  • window.innerHeight:视口的高。

客户区

元素的客户区大小(client dimension),指的是元素内容及其内边距所占据的空间大小

  • clientWidth:内容可视区的宽度。
  • clientHeight:内容可视区的高度。

1、如果有滚动条clientWidth = 元素宽 + padding(左右) - 滚动条

2、如果没有滚动条clientWidth = 元素宽 + padding(左右)

3、获取页面大小:let pageWidth = document.documentElement.clientWidth || document.body.clientWidth(ie7之前的版本);

网页大小

网页大小由呈现的页面内容的宽度和高度组成。

  • scrollWidth:实际内容的宽度。没有垂直滚动条时与clientWidth相同。否则是等于实际内容的宽度 + padding。scrollWidth也包括 ::before 和 ::after这样的伪元素。
  • scrollHeight:实际内容的高度。没有垂直滚动条时与clientHeight相同。否则是等于实际内容的高度 + padding。scrollHeight也包括 ::before 和 ::after这样的伪元素。

滚动距离

  • scrollLeft:元素最左端和窗口中可见内容的最左端之间的距离。即当前左滚的距离
  • scrollTop:元素最顶端和窗口中可见内容的最顶端之间的距离。即当前上滚的距离

1、如果有滚动条scrollLeft = 隐藏内容宽度 + border
2、如果没有滚动条scrollLeft = 0

附录

关于scrollX, pageXOffset, scrollLeft,一般使用如下:

  1. window.scrollX;
  2. window.pageXOffset;
  3. document.documenetElement.scrollLeft 如果你想获取文档距离左边滚动的像素大小,你可以采用以下方法:
  • window对象的pageXOffset属性总是可以返回滚动的长度,不管doctype是什么类型的,所有浏览器都支持这个属性,除了IE8及其更低版本的IE浏览器。
  • window对象的scrollX属性总是可以返回滚动的长度,不管doctype是什么类型,Firefox, Chrome和Safari都支持该属性。
  • 如果文档中没有指明文档类型,在IE, Firefox, Opera, Chrome和Safari中,通过body的scrollLeft可以获取滚动的数值。
  • 如果有指明文档类型,那么在IE, Firefox和Opera中,可以通过html的scrollLeft属性获取滚动的数值,但是在Chrome和Safari中的值总是为0.
  • 如果没有指明文档类型,那么html的scrollLeft属性总是返回0. 综合以上的信息,我们可以得出获取滚动条滚动数值的方法如下:
var scrollLeft =  window.scrollX != undefined ? window.scrollX : window.pageXOffset;
scrollLeft = scrollLeft != undefined ? scrollLeft : (document.documentElement || document.body).scrollLeft;

偏移量

偏移量包括元素在屏幕上占用的所有可见的空间。元素的可见大小由其高度、宽度决定,包括所有内边距、滚动条和边框大小(注意,不包括外边距)。

  • offsetHeight:元素在垂直方向上占用的空间大小,包括元素的高度、(可见的) 水平滚动条的高度、上边框高度和下边框高度。
  • offsetWidth:元素在水平方向上占用的空间大小。包括元素的宽度、(可见的)垂 直滚动条的宽度、左边框宽度和右边框宽度。
  • offsetLeft:当前元素内容区域(包括border)左边缘到 offsetParent 内容区域(不包括border)左边缘的距离。
  • offsetTop:当前元素内容区域(包括border)顶部到 offsetParent 内容区域(不包括border)顶部的距离。

offsetWidth = 元素宽 + padding(左右)+ border(左右)+ 滚动条宽度

关于offsetParent

HTMLElement.offsetParent是一个只读属性,返回一个指向最近的(closest,指包含层级上的最近)包含该元素的定位元素。如果没有定位的元素,则offsetParent为最近的table,table cell或根元素(标准模式下为html;quirks模式下为body)。当元素的style.display设置为"none"时,offsetParent返回nulloffsetParent很有用,因为offsetTopoffsetLeft都是相对于其内边距边界的

下面来探究几种可能的情况:

  1. 元素自身有fixed定位,父元素不存在定位,则offsetParent的结果为null(firefox中为:body,其他浏览器返回为null)
  2. 元素自身无fixed定位,且父元素也不存在定位,offsetParent为元素
  3. 元素自身无fixed定位,且父元素存在定位,offsetParent为离自身最近且经过定位的父元素
  4. 当元素的 style.display 设置为 "none" 时,offsetParent 返回 null。
  5. 元素的offsetParent是null

下面是在chrome中的测试结果,编号与上述对应

<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="test1" style="position: fixed"></div>
    <div id="test2"></div>
    <div id="div0" style="position: absolute">
      <div id="div1" style="position: absolute">
        <div id="test3"></div>
      </div>
    </div>
    <div id="test4" style="display: none"></div>
    <script>
      console.log(document.getElementById('test1').offsetParent); //【1】:null
      console.log(document.getElementById('test2').offsetParent); // 【2】:<body>
      console.log(document.getElementById('test3').offsetParent); // 【3】:<div id="div1">
      console.log(document.getElementById('test4').offsetParent); // 【4】null
      console.log(document.body.offsetParent); // 【5】null
    </script>
  </body>
</html>

简单🌰:

<main style="position: relative" id="main">
  <article>
    <div id="example" style="position: absolute; left: 180px; top: 180px">...</div>
  </article>
</main>
<script>
  alert(example.offsetParent.id); // main
  alert(example.offsetLeft); // 180
  alert(example.offsetTop); // 180
</script>

演示

举一个🌰作为演示

<div id="example">
  ...Text...
</div>
<style>
  #example {
    width: 300px;
    height: 200px;
    border: 25px solid #E8C48F;
    padding: 20px;
    overflow: auto;
  }
</style>

这里的div元素,具有border, padding和滚动条(margin不属于元素的部分,这里不给),该元素如下所示👇:

如果没有滚动条内容宽度为300,但是如果滚动条为16px宽(设备和浏览器之间的宽度可能有所不同),则仅保留300 - 16 = 284px宽度,因此我们应将其考虑在内。

关于元素大小和偏移的详细标注如下:

偏移量

  • offsetWidth = 390:内部CSS宽度(300px)+ padding(2 * 20px)+ border(2 * 25px)。
  • offsetHeight = 290:外部高度。

客户区

在这个示例中我们可以用clientTopclientLeft来测量元素border:

  • clientLeft = 25:左边框宽度
  • clientTop = 25:顶部边框宽度

文档从右到左(操作系统为阿拉伯语或希伯来语)时。滚动条不在右侧,而是在左侧,这个时候clientLeft还包括滚动条宽度。(这种情况比较少见,可以忽略)

前面说到clientWidth/Height提供内容可视区的大小,包括内容宽度和border,但没有滚动条:

  • clientHeight = 240:没有水平滚动条,因此它恰好是边框内部内容的总和:CSS高度200px + 顶部和底部padding(2 * 20px)。或者offsetHeight290 - border(2 * 25px)
  • clientWidth = 324:内容高度为284px + 左右padding 40px。或者offsetWidth390px - border(2 * 25px)- 滚动条宽度16 当没有padding时,我们可以clientWidth/clientHeight用来获取内容区域的大小。

滚动

scrollWidth/Height属性类似于clientWidth/clientHeight,但是它们还包括滚动(隐藏)的部分:

  • scrollHeight = 723:是内容区域的整个内部高度,包括滚动部分。
  • scrollWidth = 324:是整个内部宽度,这里我们没有水平滚动,所以等于clientWidth。 扩展

使用这些属性可以将元素扩展到整个宽度/高度:

element.style.height = `${element.scrollHeight}px`;

属性scrollLeft/scrollTop是元素的隐藏,滚动部分的宽度/高度。

在下面的图片👇我们可以看到scrollHeightscrollTop的关联:

可以把scrollTop说成是“向上滚动了多少”。

执行elem.scrollTop += 10。这会使元素内容向下滚动10px。设置scrollTop为0或较大的值,例如1e9将使元素分别滚动到最上/最下。

附言

阅读完这篇文章希望你现在对如何确定各种尺寸有了更好的了解。❤️

参考文章 📜

❤️ javaScript高级程序设计(第三版)

❤️ 深入理解定位父级offsetParent及偏移大小

❤️ help.dottoro.com/ljfswxte.ph…

❤️ developer.mozilla.org/zh-CN/docs/…

❤️ www.cnblogs.com/miss-radish…

扩展 🏆

如果你觉得本文对你有帮助,可以查看我的其他文章❤️:

👍 10个简单的技巧让你的 vue.js 代码更优雅🍊

👍 零距离接触websocket🚀

👍 Web开发应了解的5种设计模式

👍 Web开发应该知道的数据结构