测试环境是IE8,Chrome38,Firefox40,下面是全局通用脚本打印代码
/** * 打印 */ function write(str) { document.write(str + '<br/>'); }
一、尺寸
在container外面我还套了个container_out,宽度为1000px,方便演示用,HTML代码如下:
<div class="container_out"> <div id="container"></div> </div>
var container = document.getElementById('container'); /** * 通用获取CSS属性 */ function getStyle(el, name) { if(window.getComputedStyle) {//标准浏览器 return window.getComputedStyle(el, null).getPropertyValue(name); }else {//IE浏览器 //需要变成驼峰方式 name = name.replace(/\-(\w)/g, function(word, first) { return first.toUpperCase(); }); return el.currentStyle.getAttribute(name); } }
1)CSS获取width、height
分别在container中,width写为200px、10%和不设置。
/** * 使用CSS,px %,不设置 */ var cssWidth = getStyle(container, 'width'); write(cssWidth);
在3个浏览器中展现的有所不同,如下面表格中所示,IE展现的就是比较与众不同:
firefox |
chrome | IE8 | |
width:200px |
200px |
200px | 200px |
width:10% |
100px |
100px | 10% |
宽度不设置 |
956px |
956px | auto |
display:none;width:200px |
200px |
200px | 200px |
display:none;宽度不设置 |
auto |
auto | auto |
position:absolute;width:200px |
200px |
200px | 200px |
position:absolute;宽度不设置 |
0px |
0px | auto |
2)offsetWidth、offsetHeight
这是HTMLElement类中的两个属性。
offsetWidth = width+padding+border
offsetHeight = height+padding+border
/** * offsetWidth、offsetHeight */ var offsetWidth = container.offsetWidth; write(offsetWidth);
这里获取到的数据是没有单位的,浏览器结果如下:
firefox |
chrome | IE8 | |
width:200px |
224 |
224 | 224 |
width:10% |
124 |
124 | 124 |
宽度不设置 |
980 |
980 | 980 |
display:none;width:200px |
0 |
0 | 0 |
display:none;宽度不设置 |
0 |
0 | 0 |
position:absolute;width:200px |
224 |
224 | 224 |
position:absolute;宽度不设置 |
24 |
24 | 24 |
结合公式和第一张表中对应的数据可以计算出结果
当display:none的时候,得到的数据都为0
3)innerWidth、innerHeight、outerWidth和outerHeight
这4个window属性在IE6、IE7和IE8不支持。
在Firefox中,Window.outerWidth和Window.outerHeight返回浏览器窗口本身的尺寸。而Window.innerWidth和Window.innerHeight则表示该容器中页面视图区的大小(减去边框宽度)。
在Chrome中,outerWidth.outerHeight与innerWidth,innerHeight返回相同的值,即视口(viewport)大小而非浏览器窗口大小。
firefox |
chrome | IE8 | |
innerWidth |
1366 |
1366 |
undefined |
outerWidth |
1382 |
1366 | undefined |
这里顺便介绍两个概念:「css像素」、「设备像素」;css像素和设备像素 是容纳的关系。在缩放倍数是200%的情况下,1个css像素容纳了4个设备像素
我用chrome浏览器,“control+鼠标滚轮”进行放大,放到到200%的时候“innerWidth=683”,正好是原来的一半。
所以window.innerWidth度量单位是css pixels。经测试,“offsetWidth”与“clientWidth”也是css pixels,而“screen.width”是设备像素。
4)clientWidth、clientHeight
这两个是Element类中的属性。
IE中clientWidth和clientHeight属性,用于取得元素的可视区域的尺寸,不包含滚动条【innerWidth包含滚动条】、隐藏元素和边框。在body中设置高度为2000px,出现滚动条。
/** * clientWidth、clientHeight * 标准模式:document.documentElement.clientWidth * 怪异模式:document.body.clientWidth */ var clientWidth = document.documentElement.clientWidth || document.body.clientWidth; write('clientWidth:'+clientWidth);
firefox | chrome | IE8 | |
clientWidth |
1349 | 1349 |
1345 |
5)scrollWidth、scrollHeight
IE、Opera中:Element.scrollWidth = 网页内容实际宽度,可以小于clientWidth
FF:scrollWidth = 网页内容宽度,不过最小值是clientWidth
在MDN上查看Element.scrollHeight
/** * scrollWidth、scrollHeight */ var scrollWidth = document.documentElement.scrollWidth; write('scrollWidth:'+scrollWidth);
firefox |
chrome | IE8 | |
scrollWidth |
1349 |
1349 |
1345 |
二、坐标
#container{ display: none; /*其他属性一样*/ } .coordinate_out { position: relative; top:100px; left:100px; width: 500px; } #coordinate{ left:100px; top:250px; height:30px; width: 30px; background: #9ACD32; position: absolute; border: 2px solid red; }
接下来的操作会将#container隐藏掉,CSS添加一条属性:display: none;
1)offsetTop、offsetLeft
<div class="coordinate_out"> <div id="coordinate"></div> </div>
即使一个元素没有被定位,它的HTMLElement.offsetTop和HTMLElement.offsetLeft也是有效的。
它们是相对于offsetParent的距离,一级级向上累加,就得到相对页面的坐标。
/** * 累加页面坐标 */ function offsetSum(node) { var top=0, left=0 while(node) { top = top + parseInt(node.offsetTop); left = left + parseInt(node.offsetLeft); node = node.offsetParent; } return {top: top, left: left} }
firefox |
chrome | IE8 | |
top |
350 |
350 |
350 |
left |
200 |
200 | 200 |
2)node.getBoundingClientRect()
node.getBoundingClientRect()方法的返回值是一个包含了一组文本矩形的文本矩形对象。
返回值是一个DOMRect对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集合 。
在IE8或者更低浏览器版本中,getBoudingClientRect()方法返回的对象中没有height和width属性。
1.外面不套relative
<div id="coordinate"></div>
left和top与上面的CSS中定义的一样。
firefox |
chrome | IE8 | |
top |
250 |
250 |
250 |
left |
100 |
100 | 100 |
width |
30 |
30 | undefined |
height |
30 |
30 | undefined |
2.外面套个relative
<div class="coordinate_out"> <div id="coordinate"></div> </div>
与上面累加计算的结果一致,可以看到自己会做计算:
left = left + 父级的left;top = top + 父级的top。
firefox |
chrome | IE8 | |
top |
350 |
350 |
350 |
left |
200 |
200 | 200 |
3)clientLeft、clientTop
Element.clientLeft:一个元素的左边框的宽度,以像素表示。clientLeft 不包括左外边距和左内边距。clientLeft 是只读的。
Element.clientTop:一个元素顶部边框的宽度(以像素表示)。不包括顶部外边距或内边距。clientTop 是只读的。
在coordinate中加了border: 2px solid red,三个浏览器返回的都是2
/**
* clientTop clientLeft
*/
var client_top = coordinate.clientTop;
var client_left = coordinate.clientLeft;
write('client-top:'+client_top);
write('client-left:'+client_left);
4)scrollTop、scrollLeft和pageYOffset、pageXOffset
“外层元素中的内容”高过了“外层元素”本身.当向下拖动滚动条时,有部分内容会隐没在“外层元素的上边界”之外。
Element.scrollTop:指的就是这部分“不可见的内容”的高度。
window.pageYOffset:指的是滚动条顶部到网页顶部的距离,IE6、IE7、IE8不支持此属性。
我给body设置了高度2000px,然后把滚动条下拉到最下面做测试:
firefox |
chrome | IE8 | |
window.pageYOffset |
1392 |
1317 |
undefined |
document.documentElement.scrollTop |
1392 |
0 | 1416 |
document.body.scrollTop |
0 |
1317 | 0 |
在做IE8的测试的时候,每次返回的都是0,无奈只能写个onscroll事件,实时添加高度,并在html中新增标签p:
<p id="scroll"></p>
/** * pageYOffset scrollTop pageXOffset scrollLeft */ var page_YOffset = window.pageYOffset; var page_escrollTop = document.documentElement.scrollTop; var page_bscrollTop = document.body.scrollTop; write('page-YOffset:'+page_YOffset); write('element-scrollTop:'+page_escrollTop); write('body-scrollTop:'+page_bscrollTop); window.onscroll = function() { var onscroll_top = document.documentElement.scrollTop; document.getElementById('scroll').innerHTML = 'scrollTop:' + onscroll_top;; }
通过上面的数据可以看到,虽然数字不一样,但是都是通过不太一样的属性获取到的,所以需要做兼容性的处理:
var scrollTop = window.pageYOffset|| document.documentElement.scrollTop || document.body.scrollTop;
demo下载:
http://download.csdn.net/detail/loneleaf1/9132279
参考资料:
http://www.jxbh.cn/newshow.asp?id=1363&tag=2 跨浏览器窗口大小兼容js及innerWidth、innerHeight、outerWidth和outerHeight属性
http://www.zhangxinxu.com/wordpress/2012/05/getcomputedstyle-js-getpropertyvalue-currentstyle/ 获取元素CSS值之getComputedStyle方法熟悉
http://www.cnblogs.com/fullhouse/archive/2012/01/16/2324131.html JS中关于clientWidth offsetWidth scrollWidth 等的含义
《JavaScript框架设计》 人民邮电出版社 司徒正美
http://javascript.info/tutorial/coordinates Coordinates
http://www.zhangxinxu.com/wordpress/2011/09/cssom%E8%A7%86%E5%9B%BE%E6%A8%A1%E5%BC%8Fcssom-view-module%E7%9B%B8%E5%85%B3%E6%95%B4%E7%90%86%E4%B8%8E%E4%BB%8B%E7%BB%8D/ CSSOM视图模式(CSSOM View Module)相关整理
http://www.hujuntao.com/web/javascript/something-about-javascript-scrolltop.html 关于javascript scrollTop那点事
http://www.penglig.com/post-322.html 浏览器模式与窗口 scrollTop 的兼容性问题总结
https://segmentfault.com/a/1190000004403496 理解flexible.js所需的viewport知识