当前位置: 代码迷 >> 跨浏览器开发 >> 深入挖掘 offsetParant 元素的判定
  详细解决方案

深入挖掘 offsetParant 元素的判定

热度:6080   发布时间:2013-02-26 00:00:00.0
【分享】深入挖掘 offsetParant 元素的判定
在处理某些JS程序的时候,往往会用到一个元素的坐标值,如果,把页面的左上角当作是原点,那么,如何正确的取到一个元素的坐标值呢?一般来说,会采用元素的 offsetLeft 值取得横轴的坐标, offsetTop 值取得纵轴的坐标。某元素 offsetLeft 和 offsetTop 属性值是偏移量没错,关键在于,它针对哪个元素的偏移值?是它的直接父元素吗?…… 其实应该是它的 offsetParent。而且,要求它的确切坐标,也需要递归计算它所有的 offsetParent 的相对坐标值,直到 offsetParent 是null为止。看来,offsetParent 是关键。

对于元素A的offsetParent,W3C标准的 CSSOM 规范,对此作了规定。我们现在就跟据标准挖掘一下,各浏览器到底是不是一致,是不是遵守标准。

如何元素 A 的 offsetParant 元素 B

A是根元素或 BODY 则 offsetParent 元素为null
HTML code
<html id="_html"><script>    function op(id) {       var off = document.getElementById(id);       return id + " offsetParent : " + (!!off.offsetParent ? off.offsetParent : "null");    }    window.onload = function() {       document.getElementById("info").innerHTML =               op("_body") + "</br>" + op("_html");    }</script><body id="_body"><div id="info"></div></body></html>
可见,html和body的offsetParent 都不存在。这时,不存在兼容性问题。


A的 position特性计算后的值是 fixed 则 offsetParent元素为null
HTML code
<html id="_html"><script>    function op(id) {       var off = document.getElementById(id);       return id + " offsetParent : " + (!!off.offsetParent ? off.offsetParent.id : "null");    }    window.onload = function() {       document.getElementById("info").innerHTML =               op("_fixed");    }</script><body id="_body"><div id="_fixed" style="position:fixed;">fixed</div><div id="info"></div></body></html>
此时,存在兼容性问题。
Opera/Chrome/Safari中输出的是:_fixed offsetParent : null
Firefox/IE中会输出:_fixed offsetParent : _body
可见,在Firefox和IE中,固定定位的元素的offsetParent是 BODY 元素,明显是不符合W3C标准的。注意,在IE中 BODY 是默认拥有布局的,BODY是默认触发hasLayout的。

position 特性计算后的值是非 ‘static’ 的祖先元素B
HTML code
<html id="_html"><script>    function op(id) {       var off = document.getElementById(id);       return id + " offsetParent : " + (!!off.offsetParent ? off.offsetParent.id : "null");    }    window.onload = function() {       document.getElementById("info").innerHTML = op("_normaldiv");    }</script><body id="_body"><div id="_positioned" style="position:relative;">    <div id="second">       <div id="_normaldiv"></div>    </div></div><div id="info"></div></body></html>
所有浏览器中的输出都是:_normaldiv offsetParent : _positioned
此时无兼容性问题。

修改一下代码,<div id="second">外面再套一个 DIV,并且此 DIV 在IE中触发了hasLayout(设置了 ‘width:100px;’):
HTML code
<html id="_html"><script>    function op(id) {       var off = document.getElementById(id);       return id + " offsetParent : " + (!!off.offsetParent ? off.offsetParent.id : "null");    }    window.onload = function() {       document.getElementById("info").innerHTML = op("_normaldiv");    }</script><body id="_body"><div id="_positioned" style="position:relative;">    <div id="first" style="width:100px;">       <div id="second">           <div id="_normaldiv"></div>       </div>    </div></div><div id="info"></div></body></html>