var scrollHeight = divP.scrollHeight;
var scrollWidth = divP.scrollWidth;
divD.innerHTML += 'scrollHeight: ' + scrollHeight + '<br/>';
divD.innerHTML += 'scrollWidth: ' + scrollWidth + '<br/>';
</script>
在FireFox和IE10(IE10以下版本盒模型和W3C标准不一致,不加讨论,兼容性问题下面会介绍到)下得到结果scrollHeight: 494,而在Chrome和Safari下得到结果scrollHeight: 502,差了8px,根据8可以简单推测是divParent的padding,来算一下是不是
我们可以看看它们的结果是怎么来的,首先scrollHeight肯定包含了divDisplay所需的高度 400px的高度+上下各10px的padding+上下各3px的border+上下各30px的margin,这样
400+10*2+3*2+30*2=486
这样486+8=494, 486+8*2=502果真是这样,在FireFox和IE10下没有计算下padding
有了这些基础知识后,我们就可以计算元素的位置和尺寸了。
相对于文档与视口的坐标
当我们计算一个DOM元素位置也就是坐标的时候,会涉及到两种坐标系,文档坐标和视口坐标。
我们经常用到的document就是整个页面部分,而不仅仅是窗口可见部分,还包括因为窗口大小限制而出现滚动条的部分,它的左上角就是我们所谓相对于文档坐标的原点。
视口是显示文档内容的浏览器的一部分,它不包括浏览器外壳(菜单,工具栏,状态栏等),也就是当前窗口显示页面部分,不包括滚动条。
如果文档比视口小,说明没有出现滚动,文档左上角和视口左上角相同,一般来讲在两种坐标系之间进行切换,需要加上或减去滚动的偏移量(scroll offset)。
为了在坐标系之间进行转换,我们需要判定浏览器窗口的滚动条位置。window对象的pageXoffset和pageYoffset提供这些值,IE 8及更早版本除外。也可以通过scrollLeft和scrollTop属性获得滚动条位置,正常情况下通过查询文档根节点(document.documentElement)来获得这些属性值,但在怪异模式下必须通过文档的body上查询。
复制代码 代码如下:
function getScrollOffsets(w) {
var w = w || window;
if (w.pageXoffset != null) {
return { x: w.pageXoffset, y: pageYoffset };
}
var d = w.document;
if (document.compatMode == "CSS1Compat")
return { x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop };
return { x: d.body.scrollLeft, y: d.body.scrollTop };
}
有时候能够判断视口的尺寸也是非常有用的
复制代码 代码如下:
function getViewPortSize(w) {
var w = w || window;
if (w.innerWidth != null)
return { w: w.innerWidth, h: w.innerHeight };
var d = w.document;
if (document.compatMode == "CSS1Compat")
return { w: d.documentElement.clientWidth, h: d.documentElement.clientHeight };
return { w: d.body.clientWidth, h: d.body.clientHeight };
}
文档坐标
任何HTML元素都拥有offectLeft和offectTop属性返回元素的X和Y坐标,对于很多元素,这些值是文档坐标,但是对于以定位元素后代及一些其他元素(表格单元),返回相对于祖先的坐标。我们可以通过简单的递归上溯累加计算
复制代码 代码如下:
function getElementPosition(e) {
var x = 0, y = 0;
while (e != null) {
x += e.offsetLeft;
y += e, offsetTop;
e = e.offsetParent;
}
return { x: x, y: y };
}
尽管如此,这个函数也不总是计算正确的值,当文档中含有滚动条的时候这个方法就不能正常工作了,我们只能在没有滚动条的情况下使用这个方法,不过我们用这个原理算出一些元素相对于某个父元素的坐标。
视口坐标