欢迎各位兄弟 发布技术文章
这里的技术是共享的
一 背景
本文不讨论普通元素的大小和位置,仅仅讨论页面的大小和位置,而且为了简化问题,本文只讨论高度与顶部距离。笔者发现,页面的宽度与高度的表现有很多不同,细心的朋友会发现,故页面宽度另起文讨论,文章已经写好,见页面宽度发微。
这里说的页面高度,是指浏览器页面的高度。有以下四种元素能够表现页面的高度:window,html,document,body。这些元素 的高宽常常不被人注意,却经常使用,比如弹出层的居中,拖动层的拖动范围,页面布局等等问题都离不开页面的高宽及定位。上面四个元素或对象 中,window最为特殊,属于javascript中的BOM系列,而html,document,body属于javascript中的DOM系列。 下面将分别讨论。
二 我们关心那些高度?
在我看来,真正常用的页面高度只有3个,这三个高度的确定可不是一件容易的事。本文的目的就是阐述并总结三个高度的取得。这三个值是:
1.窗口高度,就是我们一眼能看到的浏览器窗口中内容显示的高度,随着浏览器的缩放而改变。
2.文档高度,由html页面的实际内容决定,不收浏览器窗口的缩放而改变,包括我们看不见的滚动条的后面,如果浏览器内容区是一页白纸,将白纸完全摊开,其高度就是文档高度。
3.被卷起的高度,当页面出现垂直滚动条,并且页面下拉了一部分,这时顶端会因为滚动条而隐藏一些高度,该值在自适应布局时具有重要意义,姑且称为被卷起的高度。
以上三个值或许是我们真正关心的,在布局,定位,自适应,拖动,弹出层等前端技术上具有价值,而由于浏览器的差异,其取值方法标准不一,常常让人痛苦不堪。jQuery面世之后,号称一统天下,笔者仔细研究之后,发现jQuery对这三个值也不是完全统一的。
三 window
window是什么呢?window就是窗口,在DOM树生成之前就有了,可以说是浏览器天生的,即使没有 后来的js,html,document,body等概念的混淆,window依然是存在的,就像是一个普通的win32程序窗口,这个win32程序的 width,height是什么,这个就很好理解了,就是我们能看到了width,height。在浏览器中,window对象专指页面窗口。所以 window对象能对大小定位有作用的只用这两个属性。而且这两个属性永远会真实的反映页面窗口的高宽。而window原生并没有 width,height属性,而有一堆杂乱的属性,为何会如何安排,以后起文专题。所以建议使用jQuery的$(window)的 height(),width()方法,这个方法忠实的反映了页面的窗口大小,并且能随着浏览器缩放而改变。如图:
window的高度表现出来,还有scrollTop()等函数,这些方法本不应该属于window对象,jquery为了封装,故如此。 jQuery在这里做的很好,$(window).scrollTop()的值真实的反映了上文所述“被卷起的高度”,可贵的是,在IE6到chrome 的所有浏览器中,表现都是一致的。
这样,我们初战告捷,一举掌握了三个高度中两个值获取的方法。归纳起来是:
1.窗口高度,$(window).height()
2.被卷起的高度,$(window).scrollTop()
不要小看这个结果,也是我们苦苦甄别之下才得出的结果。到后面我们会发现,以下各值也能反映窗口高度:
1.Firefox下document.documentElement的clientHeight,(document.documentElement即html元素)
2.chrome下的document.documentElement的clientHeight,
3.IE 7 8 9下的document.documentElement的clientHeight,
4.IE6下的document.body的clientHeight,
看的出来,大统一中有一个IE6作乱,于是还是取$(window).height()的值更加统一。
能反映被卷起的高度的值也非常多,多而易乱,让人眼花,以下各值也能反映被卷起的高度:
1.Firefox下的$(document.documentElement).scrollTop(),
2.Firefox下的$(document).scrollTop(),
3.Firefox下的document.documentElement.scrollTop,
4.Chrome下的$(document).scrollTop(),
5.Chrome下的$(document.body).scrollTop(),
6.Chrome下的document.body.scrollTop,
7.IE6下的$(document).scrollTop(),
8.IE6下的$(document.body).scrollTop(),
9.IE6下的document.body.scrollTop,
10.IE7下的$(document.documentElement).scrollTop(),
11.IE7下的$(document).scrollTop(),
12.IE7下的document.documentElement.scrollTop,
13.IE8下的$(document.documentElement).scrollTop(),
14.IE8下的$(document).scrollTop(),
15.IE8下的document.documentElement.scrollTop,
由 此可见,除了$(window).scrollTop()能真实反映被卷起的高度之外,还有一个也可以, 即$(document).scrollTop(),而在原生的scrollTop值中,没有统一的值。建议使 用$(window).scrollTop()的值,便于记忆。$(document).scrollTop()便于理解,因为卷起毕竟是由于文档在窗口 中放不下而产生的。
四 Html
所有浏览器都支持document,要说清楚document的前生后世,就要从文档说起。html页面的本质就是一棵树。根节点就是document。document和DOM JS中规定的HtmlElement对象一样,也有表达高度和偏移的属性。所有HtmlElement的元素都有几个属性:
offsetHeight:元素所占高度;
offsetTop:元素上边框到父元素上边框的距离;
clientHeight:元素的客户区高度,就是offsetHeight减掉边框的值;
scrollHeight:元素有垂直滚动条时,元素铺开的高度,即内容的真实高度。
scrollTop:因垂直方向的滚动条,而在顶端被隐藏的距离。
第一个HtmlElement元素就是html,取得方法为document.documentElement不要感到惊讶,确实是这样。我们来观察一下html页面的基本结构:
<html>
<head></head>
<body></body>
</html>
从此可以看出<html></html>是一个元素,并且是网页的第一个元素。 document.documentElement.offsetHeight,offsetTop,clientHieight,scrollHeight,scrollTop 等都有值,但是在各浏览器上表现不一。offsetHeight的基本含义是:整个网页的高度,即完全铺开的高度。还有一个 值$(document.documentElement).height()的值在各浏览器下表现也是不一的,所以该值不再深究。
五 Document
关于document的高度,是jQuery封装的,应为document本身不是一个 HtmlElement对象,但是这个封装的值非常准确,而且在各浏览器下表现完全一致。所以$(document).height()的值非常可靠,能 真实的反映前面所提的"文档高度",所以我们又发现了一个值,即
1.文档高度,$(document).height()
六 Body
body的高宽经常被使用,作为页面高度的代表。但是,经过笔者仔细研究,发现body能反映的一些高度值在各浏览器下表现让人不满, 本文前面提到的三个目标值都已经获得了,再说说body也无妨,但是body的高度相关值大可不必使用。
body.offsetHeight的值是如何计算的?又是我们发现该值比document.documentElement.offsetHeight的值要小,为何?body.offsetHeight的值永远不会超过document.documentElement.offsetHeight, 我们知道,html元素表现的是文档的高度,是被撑出来的。而body的高度不是这样计算的,body的高度其实是文档所占用的高度,两者微妙的差距就在 于:后者忽略了顶部块元素的margin-top和底部块元素的margin-bottom。这个结论符合offsetHeight的原始意义,在上文元素大小和位置中已有阐述,offsetHeight表达的是元素所占的高度,含padding,height,border等,而margin是个定位的概念,与元素所占高度无关。
如果是普通元素,我们会关心元素所占高度offsetHeight,但是body的offsetHeight属性表达的值,一般不是我们想要的。
七 总结
综上所述,我们关心的三个页面高度都有了取值方法,总结为: