欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浏览器有关的宽高详解

程序员文章站 2022-04-10 14:55:44
...

简介

window对象表示浏览器打开的窗口(可以省略,全局变量挂载在window对象下,alert,confirm等方法)。document对象是HTML文档,是window对象的一部分(document.body可以写成window.document.body)。

与window有关的宽高介绍

window.innerHeight和window.outerHeight的区别在于,前者是浏览器内部文档的高度,后者是整个浏览器窗口的高度。window.innerWidth和window.outerWidth一般相同。
window.screen代表用户的屏幕。window.screen.height代表整个屏幕的高度,window.screen.availHeight代表屏幕中可利用的高度(比前者少了一个菜单栏)。window.screen.width和window.screen.availWidth相同。
screenTop代表浏览器距离屏幕顶部的距离,screenLeft为浏览器距离屏幕左边的距离.

兼容性问题

window.innerHeight和window.innerWidth(可视区域)在IE8及其以下浏览器是不支持的。所以我们要使用这样的兼容方案

   var seeWidth = document.ducumentElement.clientWidth ||
      document.body.clientWidth;
   var seeHeight = document.ducumentElement.clientHeight ||
      document.body.clientHeight;

documentElement

document是文档元素,nodeType = 9,nodeName = #document。documentElement的nodeType = 1, nodeName = HTML。
body既可以通过document.body拿到,也可以通过documentElement的childNodes得到。

document的宽高

这里我们分成三部分:

  • 与client相关的宽高
  • 与offset相关的宽高
  • 与scroll相关的宽高

与client相关的宽高

元素.clientWidth和元素.clientHeight指的是元素的可视部分宽度和高度,即padding + content。(注意如果元素被隐藏了,他的宽高就没有值)。如果没有滚动条,即为元素设定的高度和宽度。如果出现滚动条(比如元素overflow: scroll),那么该属性就是其本来宽高减去滚动条的宽高。举一个栗子:

   body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   //430(350 + 80)
   console.log(document.body.clientHeight);
   //580,不包含border
   console.log(document.body.clientWidth);

那么我们再来看一个div

   #main {
      width: 200px;
      height: 200px;
      background: red;
      border: 1px solid #000;
      overflow: auto;
   }
   //我们在div中不断添加文字直到出现滚动条
   var div = document.getElementById('main');
   //200
   console.log(div.clientHeight);
   //在windows下是183,在mac下是200(滚动条没显示的时候)
   console.log(div.clientWidth);

那么我们总结一下

   //假如无padding无滚动
   clientWidth = style.width
   //假如有padding无滚动
   clientWidth = style.width + style.padding * 2;
   //假如有padding有滚动,且滚动是显示的
   clientWidth = style.width + style.padding * 2 - 滚动轴宽度

IE6以上浏览器都支持clientHeight和clientWidth。
元素的clientLeft和clientTop这两个返回的是元素周围边框的厚度,如果不指定一个边框或者不定位该元素,它的值就是0

    body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   //20, clientTop = border-top的border-width
   console.log(document.body.clientLeft);
   //20,clientLeft = border-left的border-width
   console.log(document.body.clientTop);

与offset相关的宽高

offsetWidth和offsetHeight指的是元素的border + padding + content的宽度和高度,该属性和内部的内容是否超出元素大小无关,只和本来设定的border以及width和height有关,还是上面的栗子

   body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   //470(350 + 80 + 40)
   console.log(document.body.offsetHeight);
   //620
   console.log(document.body.offsetWidth);

offsetWidth和offsetHeight所有浏览器的支持一致。
offsetLeft和offsetTop是基于offsetParent的。对于offsetParent,如果当前元素的父级元素没有进行CSS定位(position为absolute或relative),offsetParent为body,如果当前元素的父级元素中有CSS定位,offsetParent就取最近的那个父级元素。

   //在IE6/7中
   offsetLeft = (offsetParent的padding-left) + (当前元素的margin-left);
   //在IE8/9/10及Chrome中
   offsetLeft = (offsetParent的margin-left) + (offsetParent的border宽度) + (offsetParent的padding-left) + (当前元素的margin-left);
   //在firefox中
   offsetLeft = (offsetParent的margin-left) + (offsetParent的padding-left) + (当前元素的margin-left)

还是刚才的栗子

   body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   #main {
      width: 400px;
      height: 200px;
      background: red;
      padding: 20px;
      margin: 10px;
      border: 20px solid #000;
      overflow: auto;
   }
   //我们在div中不断添加文字直到出现滚动条
   var div = document.getElementById('main');
   //在IE6/7中
   console.log(div.offsetLeft);  //50
   console.log(div.offsetTop);   //50
   //在IE8/9/10及Chrome中
   console.log(div.offsetLeft);   //80
   console.log(div.offsetTop);    //80
   //在firefox中
   console.log(div.offsetLeft);  //60
   console.log(div.offsetTop);   //60

与scroll相关的宽高

document.body的scrollWidth和scrollHeight与普通元素如div的scollWidth和scrollHeight是有点区别的

   body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   //浏览器高度
   document.body.scrollHeight 
   //浏览器宽度
   document.body.scrollWidth 

当给定的宽高小于浏览器窗口,document.body.scrollWidth通常是浏览器窗口的宽度,document.body.scrollHeight 通常是浏览器窗口的高度。如果给定宽高大于浏览器窗口,且内容小于给定宽高,document.body.scrollWidth = 给定的宽度 + 其所有的padding、margin和border。如果给定宽高大于浏览器窗口,且内容大于给定宽高,document.body.scrollWidth = 内容的宽度 + 其所有的padding、margin和border。(有兼容性问题,上述是Chrome浏览器中)
接下来我们看一下普通元素如div中的scrollWidth

   #main {
      width: 400px;
      height: 200px;
      background: red;
      padding: 20px;
      margin: 10px;
      border: 20px solid #000;
      overflow: auto;
   }
   var div = document.getElementById('main');
   //200 + 20 * 2 = 240
   console.log(div.scrollWidth);
   //440 + 20 * 2 = 440
   console.log(div.scrollHeight);
   //接下来我们填充div的内容使其出现滚动轴

我们得出这样一个结论

   //在无滚动轴的情况 
   scrollWidth = clientWidth = style.width + style.padding * 2;
   //在有滚动轴的情况下(实际内容超出了定义的宽)
   scrollWidth = 实际内容的宽度 + padding * 2;

scrollLeft和scrollTop是可读写的,指的是当元素内容超出其宽高的时候,元素被卷起的高度和宽度。

   #main {
      width: 400px;
      height: 200px;
      background: red;
      padding: 20px;
      margin: 10px;
      border: 20px solid #000;
      overflow-y: scroll;
   }
   var div = document.getElementById('main');
   //0
   console.log(div.scrollTop);
   //0
   console.log(div.scrollLeft);
   div.scrollTop = 20;
   console.log(div.scrollTop);

可以通过这个属性获取滚动条距离顶部高度进行可视区域加载,具体可以参考我另一篇博客 lazyLoad与节流

    //可视区域
    var seeHeight = window.innerHeight || document.documentElementHeight || document.body.clientHeight;
    //滚动条距离顶部高度
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;