任何元素都拥有offsetLeft和offsetTop属性,它们用于描述元素的偏移位置。不过不同浏览器定义元素的偏移参照对象不同,例如,IE会以父元素为参照对象进行偏移,而支持DOM标准的浏览器会以最近非静态定位元素为参照对象进行偏移。
下面的示例是一个三层嵌套的结构,其中最外层p元素被定义为相对定位显示,在JavaScript脚本中使用“alert(box.offsetLeft);”语句获取最内层p元素的偏移位置,这样IE返回值为50像素,而其他支持DOM标准的浏览器会返回101像素。注意,Opera返回值为121像素,因为它以ID为wrap元素的边框外壁为起点进行计算,而其他支持DOM标准的浏览器以ID为wrap元素的边框内壁为起点进行计算,代码如下:
<style type="text/css">
p{
width:200px;height:100px;border:solid 1px red;padding:50px;
}
#wrap{
position:relative;
border-width:20px;
}
</style>
<p>
<p>
<p></p>
</p>
</p>
获取元素的位置的呈现效果如图6.10所示。
图 6.10 获取元素的位置示意图所有浏览器都支持offsetParent属性,该属性总能够指向定位参考的元素,并得到所有浏览器的认可,因此针对上面的嵌套结构,有如下几种情况。
❑对于IE来说,当前定位元素(即ID为box的p元素)的offsetParent属性将指向ID为sub的p元素。对于sub元素来说,它的offsetParent属性将指向ID为wrap的p元素。
❑对于支持DOM的浏览器来说,当前定位元素的offsetParent属性将指向ID为wrap的p元素。
可以根据以上情况设计一个能够兼容不同浏览器的等式:
❑IE:(#box).offsetLeft+(#sub).offsetLeft=(#box).offsetLeft+(#box).offsetParent.offsetLeft
❑DOM:(#box).offsetLeft
对于任何浏览器来说,offsetParent属性总能够自动识别当前元素偏移的参照对象,不用担心offsetParent在不同浏览器中具体指代什么元素。这样就能够通过迭代来计算当前元素距离窗口左上顶角的坐标值,具体演示如图6.11所示。
图 6.11 能够兼容不同浏览器的元素偏移位置计算演示图虽然不同浏览器的offsetParent属性指代的元素不同,但是通过迭代计算,当前元素距离浏览器窗口的坐标距离都是相同的。因此,根据这个规律,可以设计一个扩展函数:
//获取指定元素距离窗口左上角的偏移坐标
//参数:e表示获取位置的元素
//返回值:返回对象直接量,其中属性x表示x轴偏移距离,属性y表示y轴偏移距离
function getW(e){
var x=y=0;
while(e.offsetParent){
x+=e.offsetLeft;
y+=e.offsetTop;
e=e.offsetParent;
}
return{
"x":x,
"y":y
};
}
由于body和html元素没有offsetParent属性,因此,当迭代到body元素时,会自动停止并计算出当前元素距离窗口左上角的坐标距离。
调用该扩展函数应注意:不要为包含元素定义边框,因为不同浏览器对边框的处理方式不同。例如,IE会忽略所有包含元素的边框,因为所有元素都是参照对象,并且以参照对象的边框内壁作为边线进行计算。Firefox和Safari浏览器会把静态元素的边框作为实际距离进行计算,因为对于它们来说,静态元素不作为参照对象。而对于Opera浏览器来说,由于它以非静态元素边框的外壁作为边线进行计算,所以该浏览器所获取的值又有所不同。如果不为所有包含元素定义边框,那么可以避免不同浏览器解析的分歧,最终实现返回相同的距离。