MDN 上关于 HTMLElement.offsetParent 的描述如下:
The **HTMLElement.offsetParent
** read-only property returns a reference to the object which is the closest (nearest in the containment hierarchy) positioned containing element. If the element is non-positioned, the nearest table cell or root element (html in standards compliant mode; body in quirks rendering mode) is the offsetParent. offsetParent returns null when the element has style.displayset to "none". The offsetParent is useful because offsetTop and offsetLeft are relative to its padding edge.
关于其中的 the nearest table cell , 我做了一下验证,代码如下:
使用 table>tr>td
<!DOCTYPE html>
<html>
<head>
<style>
#test {
margin: 10px;
padding: 10px;
width: 200px;
border: 5px solid black;
}
</style>
</head>
<body onload="myFunction()">
<table>
<tr>
<td>
<div id="test">
<p>offsetParent is: <span id="demo"></span></p>
</div>
</td>
</tr>
</table>
</div>
<script>
function myFunction() {
var testDiv = document.getElementById("test");
document.getElementById("demo").innerHTML = testDiv.offsetParent.tagName;
}
</script>
</body>
</html>
使用 display:table-cell
但如果 使用 table-cell来模拟 单元格,结果就不一样了。
<!DOCTYPE html>
<html>
<head>
<style>
#test {
margin: 10px;
padding: 10px;
width: 200px;
border: 5px solid black;
}
.container {
display: table-cell;
}
</style>
</head>
<body onload="myFunction()">
<div class="container">
<div id="test">
<p>offsetParent is: <span id="demo"></span></p>
</div>
</div>
<script>
function myFunction() {
var testDiv = document.getElementById("test");
document.getElementById("demo").innerHTML = testDiv.offsetParent.tagName;
}
</script>
</body>
</html>
被包含元素使用 定位
如果被包含元素上使用了position ,则 offsetParent 也会变成 body.
<!DOCTYPE html>
<html>
<head>
<style>
#test {
margin: 10px;
padding: 10px;
width: 200px;
border: 5px solid black;
position: relative;
}
</style>
</head>
<body onload="myFunction()">
<table>
<tr>
<td>
<div id="test">
<p>offsetParent is: <span id="demo"></span></p>
</div>
</td>
</tr>
</table>
</div>
<script>
function myFunction() {
var testDiv = document.getElementById("test");
document.getElementById("demo").innerHTML = testDiv.offsetParent.tagName;
}
</script>
</body>
</html>
结论
- 如果被包含元素自身有定位
- 如果有定位祖先元素,则 offsetParent 是最近的有定位的祖先节点。
- 如果无定位祖先元素,则 offsetParent 是body。
- 如果被包含元素自身没有定位
- 如果有定位祖先元素(td table 也属于定位),则 offsetParent 是最近的有定位的祖先节点。
- 如果无定位祖先元素,则 offsetParent 是body。