浏览器有关的宽高详解

简介

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;    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值