ZetCode

JavaScript offsetParent

最后修改于 2025 年 4 月 2 日

在本文中,我们将探讨 JavaScript 中的 offsetParent 属性。此属性对于理解 DOM 层次结构中的元素定位和布局至关重要。

基本定义

offsetParent 属性返回最近的已定位(非 static)的祖先元素。如果没有已定位的祖先,则返回 body 元素,或对于隐藏的元素返回 null。

此属性是只读的,有助于确定元素的定位上下文。它对于计算相对于其容器的准确元素位置至关重要。

基本 offsetParent 示例

此示例演示了如何访问元素的 offsetParent 属性。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic offsetParent</title>
    <style>
        #container {
            position: relative;
            width: 300px;
            height: 200px;
            border: 1px solid black;
        }
        #child {
            position: absolute;
            top: 50px;
            left: 50px;
            width: 100px;
            height: 100px;
            background-color: lightblue;
        }
    </style>
</head>
<body>

<div id="container">
    <div id="child"></div>
</div>

<script>
    const child = document.getElementById('child');
    console.log(child.offsetParent.id); // Outputs: container
</script>

</body>
</html>

在此示例中,我们有一个具有相对定位的容器 div 和一个具有绝对定位的子 div。子元素的 offsetParent 是容器 div。

这表明 offsetParent 如何识别最近的已定位祖先。子元素的定位是相对于其 offsetParent(容器)计算的。

没有已定位祖先的 offsetParent

此示例显示了没有已定位祖先时 offsetParent 的行为。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>No Positioned Ancestor</title>
    <style>
        #child {
            margin: 20px;
            width: 100px;
            height: 100px;
            background-color: lightgreen;
        }
    </style>
</head>
<body>

<div id="child"></div>

<script>
    const child = document.getElementById('child');
    console.log(child.offsetParent.tagName); // Outputs: BODY
</script>

</body>
</html>

这里我们有一个没有已定位祖先的子 div。offsetParent 默认为 body 元素,因为它是最近的非 static 包含块。

这表明在没有已定位祖先的情况下,offsetParent 如何回退到 body 元素。元素的定位将相对于文档主体。

display:none 的 offsetParent

此示例演示了 display:none 元素的 offsetParent 行为。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Display None</title>
    <style>
        #container {
            position: relative;
            width: 300px;
            height: 200px;
            border: 1px solid black;
        }
        #child {
            display: none;
            width: 100px;
            height: 100px;
            background-color: lightcoral;
        }
    </style>
</head>
<body>

<div id="container">
    <div id="child"></div>
</div>

<script>
    const child = document.getElementById('child');
    console.log(child.offsetParent); // Outputs: null
</script>

</body>
</html>

在这种情况下,子元素具有 display:none。其 offsetParent 返回 null,因为隐藏的元素不参与布局。

这说明了一个重要的边缘情况。未渲染的元素(display: none 或不在 DOM 中)返回的 offsetParent 为 null,这与 visibility:hidden 不同。

fixed 定位的 offsetParent

此示例显示了 fixed 定位元素的 offsetParent 行为。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Fixed Positioning</title>
    <style>
        #fixed {
            position: fixed;
            top: 20px;
            left: 20px;
            width: 100px;
            height: 100px;
            background-color: lightyellow;
        }
    </style>
</head>
<body>

<div id="fixed"></div>

<script>
    const fixed = document.getElementById('fixed');
    console.log(fixed.offsetParent); // Outputs: null in most browsers
</script>

</body>
</html>

这里我们有一个 fixed 定位的元素。在大多数浏览器中,其 offsetParent 返回 null,因为 fixed 元素是相对于视口定位的。

这表明 fixed 定位如何影响 offsetParent。元素是相对于视口定位的,而不是任何祖先,因此返回 null。

嵌套结构中的 offsetParent

此示例演示了复杂嵌套结构中的 offsetParent。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Nested Structure</title>
    <style>
        .outer {
            position: relative;
            width: 400px;
            height: 300px;
            border: 1px solid black;
        }
        .middle {
            margin: 20px;
            width: 350px;
            height: 250px;
            border: 1px solid blue;
        }
        .inner {
            position: absolute;
            top: 50px;
            left: 50px;
            width: 100px;
            height: 100px;
            background-color: lightpink;
        }
    </style>
</head>
<body>

<div class="outer">
    <div class="middle">
        <div class="inner"></div>
    </div>
</div>

<script>
    const inner = document.querySelector('.inner');
    console.log(inner.offsetParent.className); // Outputs: outer
</script>

</body>
</html>

在此嵌套结构中,内部 div 具有绝对定位。其 offsetParent 是外部 div,它是最近的已定位祖先。

这表明 offsetParent 如何跳过非定位元素(中间的 div)来查找最近的已定位祖先。内部 div 的定位是相对于外部 div 的。

来源

MDN offsetParent 文档

在本文中,我们探讨了 JavaScript offsetParent 属性。它是理解元素定位和布局计算的强大工具。

作者

我叫 Jan Bodnar,是一名热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 JS DOM 教程