在实现页面的某些效果时,我们经常会用到JavaScript去获取浏览器窗口,页面中元素和屏幕的大小,而这三个的大小在不同的浏览器中获取的方式有所不同,所以不得不处理一些兼容性问题。
一、屏幕的大小
首先来看屏幕大小,什么是屏幕大小呢?屏幕大小是指当前所用设备的屏幕的分辨率(浏览器窗口外部显示器的大小),它一般是不变的。它们可以通过JavaScript中的screen对象的属性获取。
- screen.height:屏幕的像素高度;
- screen.width:屏幕的像素宽度;
- screen.availHeight:屏幕的可用工作区的像素高度(即屏幕的像素高度减去系统部件高度之后的值);
- screen.availWidth:屏幕的可用工作区的像素宽度(即屏幕的像素宽度减去系统部件宽度之后的值);
其中height与availHeight的区别,一般对于windows用户来说,availHeight是除去windows任务栏的高度,而height是包括了任务栏的高度,因为任务栏可以在屏幕的上下左右,所以对于width和availWidth是同理的。这四个属性都是只读的。小案例:
alert(screen.height);//768 alert(screen.availHeight);//728 alert(screen.width);//1366 alert(screen.availWidth);//1366 //对于win7用户,一般来说availHeight是height的高度减去40px
二、浏览器窗口的大小
对于IE9+、Firefox、Chrome、Safari、Opera浏览器来说在window对象上都提供了四个属性:innerHeight、innerWidth、outerHeight、outerWidth。而IE8及其以下浏览器没有提供这四个属性。对于outerHeight和outerWidth表示浏览器本身尺寸的大小,但是并不是每个浏览器都是这样的,比如在Chrome中outerHeight和innerHeight是一样的,并且在IE8及其以下浏览器根本没有提供获取浏览器窗口大小的属性,所以我们无法统一的得到各个浏览的本身尺寸的大小。但是我们可以获取浏览器中页面可见区域的大小(除去一些边框)。
在IE9+、Firefox、Chrome、Safari、Opera中可以通过innerHeight和innerWidth获取页面可见区域的大小。而对于IE8及其以下浏览器通过DOM提供了页面可见区域大小的信息,document.documentElement.clientHeight和document.documentElement.clientWidth,但如果IE6处于混在模式,需要通过document.body.clientHeight和document.body.clientWidth获取页面可见区域大小。所以跨浏览器获取页面可见区域大小如下:
var pageHeight,pageWidth; if(typeof window.innerHeight!=‘undefined‘){ //针对非IE8及其以下的浏览器 pageHeight=window.innerHeight; pegeWidth=window.innerWidth; }else{ if(document.compatMode=="CSS1Compat"){ //判断是否处于混杂模式 pageHeight=document.documentElement.clientHeight; pageWidth=document.documentElement.clientWidth; }else{ pageHeight=document.body.clientHeight; pageWidth=document.body.clientWidth; } }
window.innerHeight与document.documentElement.clientHeight或者window.innerWidth与document.documentElement.clientWidth在页面中没有出现滚动条时是一样的,当页面中出现了滚动条,window.innerHeight和window.innerWidth包含了滚动条的大小,而document.documentElement.clientHeight和document.documentElement.clientWidth没有包含滚动条的大小。比如:
//在没有滚动条下 alert(window.innerWidth); //1366 alert(document.documentElement.clientWidth);//1366 //页面中有滚动条下 alert(window.innerWidth); //1366 alert(document.documentElement.clientWidth);//1349
页面可见区的大小如图:
三、页面中元素的大小
1.偏移量
偏移量是指元素在屏幕上占用的所有可见的空间,元素的可见大小是由元素的高度,宽度,内边距,滚动条、边框决定的(不包括外边距)。
offsetWidth:元素在水平方向上占用的空间大小,其中包括元素的宽度、左右边框的大小、垂直滚动条的大小、左右内边距;
offsetHeight:元素在垂直方向上占用的空间大小,其中包括元素的高度、上下边框的大小、水平滚动条、上下内边距。
对于滚动条有如下说明:当元素里面的内容的大小超出了元素的width/height大小,并且元素的overflow属性的值为scroll时,那么元素就会出现滚动条。
①首先来说没有滚动条的情况:
offsetWidth=width+border-left-width+border-right-width+padding-left+padding-right;
offsetHeight=height+border-top-width+border-bottom-width+padding-top+padding-bottom;
如图:
②在有滚动条的情况下(包含了滚动条的大小): 如图:
<!DOCTYPE html> <html> <head> <meta charser="utf-8" /> <title>test</title> <style type="text/css"> #box{ margin:20px; width:400px; height:200px; padding:10px; border:10px solid red; background:blue; overflow:scroll; } </style> </head> <body> <div id="box"> <p>offsetWidth的大小</p> <p>offsetHeight的大小</p> <p>offsetWidth的大小</p> <p>offsetHeight的大小</p> <p>offsetWidth的大小</p> <p>offsetHeight的大小</p> <p>offsetWidth的大小</p> <p>offsetHeight的大小</p> </div> </body> <script> alert(document.getElementById("box").offsetWidth);//440=400+10+10+10+10 alert(document.getElementById("box").offsetHeight);//240=200+10+10+10+10 </script> </html>
offsetLeft:元素的左外边框至包含元素(offsetParent)的左内边框之间的像素距离。
offsetTop:元素的上外边框至包含元素(offsetParent)的右内边框之间的像素距离。
其中,offsetLeft和offsetTop属性与包含元素有关,包含元素的引用保存在offsetParent属性中。offsetParent属性的值是距离元素最近的并且已经进行css定位(absolute/relative)的祖先元素。如果祖先元素中没有进行定位的元素,那么offsetParent的值就是根元素(在标准兼容模式下为html元素;在怪异呈现模式下为body元素)的引用。offsetParent属性不一定与parentNode的值相等。但是在IE7和IE6中offsetParent的值就是parentNode的值,offsetParent的取值与父级元素是否定位没有关系,它的值始终就是该元素的父元素。比如:
<!DOCTYPE html> <html> <head> <meta charser="utf-8" /> <title>test</title> <style type="text/css"> #test1{ width:300px; height:300px; margin-left:50px; position: absolute; left:0; right:0; background:#ccc; padding:20px; border:10px solid green; } #test2{ width:150px; height:200px; background: red; padding:10px; margin:55px; border:10px solid blue; } #test3{ width:50px; height:100px; background:yellow; padding:10px; margin:20px; border:10px solid orange; } </style> </head> <body> <div id="test1"> <div id="test2"> <div id="test3"> </div> </div> </div> </body> <script> alert(document.getElementById("test3").offsetParent.id);//IE6/7是test2,其他浏览器是test1 </script> </html>
如图:
某个元素在页面上的偏移量,将这个元素的offsetLeft和offsetTop与其offsetParent元素的offsetLeft和offsetTop相加,如此循环直至根元素,就可以得到了。
function getOffset(elem){ var actualLeft=elem.offsetLeft; var actualRight=elem.offsetRight; var curr=elem.offsetParent; while(curr!==null){ actualLeft+=curr.offsetLeft; actualRight+=curr.offsetRight; curr=curr.offsetParent; } return { actualLeft:actualLeft, actualRight:actualRight }; }
2.客户区大小
元素客户区大小是指元素内容及其内边距所占据的空间大小。客户区大小的属性有两个:clientWidth和clientHeight.
clientWidth:元素内容区宽度加上左右内边距宽度;
clientHeight:元素内容区高度加上上下内边距高度;
由于浏览器渲染时会把滚动条的宽度(或高度)算在元素本身的宽度(或高度)中,并且客户区大小不计算滚动条占用空间,所以当元素出现滚动条时,客户区大小是元素内容及其内边距所占据的空间大小减去滚动条的大小。比如:
<!DOCTYPE html> <html> <head> <meta charser="utf-8" /> <title>test</title> <style type="text/css"> #client{ width:200px; height:200px; background:#ccc; padding:20px; border:10px solid blue; margin:30px; /*出现滚动条 overflow: scroll; */ } </style> </head> <body> <div id="client"> <p>clientWidth</p> <p>clientHeight</p> <p>clientWidth</p> <p>clientHeight</p> <p>clientWidth</p> </div> </body> <script> alert(document.getElementById("client").clientWidth);//无滚动条是240 有滚动条时是223 alert(document.getElementById("client").clientHeight);//无滚动条是240 有滚动条时是223 </script> </html>
3.滚动大小
滚动大小是指包含滚动内容的元素的大小。滚动大小的属性有四个:scrollWidth、scrollHeight、scrollTop、scrollLeft。
scrollWidth:元素完整的宽度即包含元素被隐藏部分的宽度;
scrollHeight:元素完整的高度即包含元素被隐藏部分的高度;
scrollTop:元素被滚动条卷上去的高度;
scrollLeft:元素被滚动条卷上去的宽度;
如图:
对于scrollTop和scrollLeft这两个属性,可以通过它们来判断元素滚动条当前的状态,也可以设置滚动位置。
参考文章:《JavaScript高级程序设计》