offsetParent与parentElement或parentNode之间的差异

时间:2013-07-31 15:42:20

标签: javascript html dom offset

我有以下DOM结构

<body>
    <div>
       <table>
          <outerElement>
              <innerElement />  
          </outerElement>
       <table>
    </div>
</body>

DIV的溢出设置为auto,因此如果表格变大,它会在DIV中滚动。

在这种情况下,当table.offsetParenttable.parentNode返回Div时,为什么parentElement会返回正文?

我需要在窗口中计算innerElement的当前位置,因此我会通过所有父元素遍历它,收集它们的offsetTopoffsetLeft值。直到DIV offsetParent工作正常,然后它直接跳到身体。如果在某些时候涉及滚动问题,我需要考虑scrollTopscrollLeft - 就像上面示例中的DIV一样。问题是如果我使用offsetParent我从未遇到DIV作为父母之一。

更新

这是执行遍历的代码的一部分:

while (oElem && getStyle(oElem, 'position') != 'absolute' && getStyle(oElem, 'position') != 'relative') { 
   curleft += oElem.offsetLeft;
   curtop += oElem.offsetTop;
   oElem = oElem.offsetParent;
}

其中getStyle是一个自定义函数,在这种情况下检索位置样式。

4 个答案:

答案 0 :(得分:34)

offsetParent是距离position:relativeposition:absolute或页面正文最近的父级。 parentNode是直接父级,无论position

答案 1 :(得分:4)

使用getBoudingClientRect()确实是一个很好的帮助(感谢Ally提示!)。

如果您仍然需要相对于文档左上角的位置,这是一个有用的代码段:

if (node.getBoundingClientRect) {
    var rect = node.getBoundingClientRect();
    var sx = -(window.scrollX ? window.scrollX : window.pageXOffset);
    var sy = -(window.scrollY ? window.scrollY : window.pageYOffset);

    return {
        x: rect.left - sx,
        y: rect.top - sy
    }
}

注意:在某些情况下,document.body.getBoundingClientRect()可能会在Firefox中为top返回意外值。因此,窗口滚动位置更加稳健。

对于尚未支持getBoundingClientRect()的客户,我们仍然必须走私父母,并注意每个overflow: scroll(或自动)父母都有position: relative

答案 2 :(得分:0)

要清除offsetParent,您必须添加大量黑客和支票,以确保您做对。

请尝试使用getBoundingClientRect

答案 3 :(得分:0)

offsetParent本质上是 UI

中的父级

parentNode实际上是 DATA / HTML

中的父级 包含

offsetParent以弃用传统的parentNode