16

我有以下 DOM 结构

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

DIV 将其溢出设置为自动,因此如果表变大 - 它会在 DIV 内滚动。

在这种情况下,为什么table.offsetParent同时返回 bodytable.parentNodeparentElement返回 Div?

我需要计算innerElement窗口内的当前位置,所以我从它向上遍历所有父元素,收集它们的offsetTopoffsetLeft值。直到 DIVoffsetParent工作正常,然后它直接跳到正文。如果在某些时候涉及滚动,我需要考虑scrollTop并且scrollLeft以及 - 就像上面示例中的 DIV 一样。问题是如果我使用offsetParent我从来没有遇到过作为父母之一的 DIV。

更新

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

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

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

4

4 回答 4

43

offsetParent is the closest parent that has position:relative or position:absolute or the body of the page. parentNode is the direct parent, regardless of position.

于 2013-07-31T15:49:25.553 回答
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
    }
}

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

对于还不支持 getBoundingClientRect() 的客户端,我们仍然必须遍历 offetParents 并注意每个overflow: scroll(或自动)父级都有position: relative.

于 2015-12-02T10:52:42.573 回答
1

远离offsetParent,您将不得不添加许多技巧和检查以确保您做对了。

尝试改用getBoundingClientRect

于 2014-02-07T11:06:07.553 回答
-1

offsetParent 本质上是UI中的父级

parentNode 实际上是DATA/HTML中的父节点

包含 offsetParent 以弃用传统的 parentNode

于 2020-04-24T01:50:51.540 回答