今天介绍下 jQuery.offsetParent() 和 原生 offsetParent 的区别,主要是处理问题时遇到到 element.offsetTop 和 $(element).position().top 返回的值不一样
offsetTop 定义,它是返回当前元素相对于其 offsetParent 元素的顶部的距离
jQuery.position() 返回当前元素相对于 offsetParent 元素位置(top/left),而这里 jQuery 说的 offsetParent 不是等同于原生的,jQuery 做了替代
接下来详细介绍两者的定义和不同
HTMLElement.offsetParent 详细查看 MDN
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.display set to “none”. The offsetParent is useful because offsetTop and offsetLeft are relative to its padding edge.
HTMLElement.offsetParent 返回一个指向最近的包含该元素的定位元素,如果没有定位元素,则 offsetParent 为最近的 table 元素对象或根元素(标准模式下为 html;quirks 模式下为 body)
HTMLElement.offsetParent 规则
- 元素的
position为fixed或者display为none, 则offsetParent为null - 元素
offsetParent查找其父节点,如果position不为static即relative/absolute/fixed,则为返回该节点 - 如果为
static(position不设置时默认为static),则继续向上层节点查询进行position判断 - 如果没有定位的元素,则
offsetParent为最近的table/td元素或者跟元素body
jQuery.offsetParent() 详细查看 jQuery
直接看实现代码
offsetParent: function() {
return this.map(function() {
var offsetParent = this.offsetParent || docElem;
while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
jQuery.css( offsetParent, "position" ) === "static" ) ) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent || docElem;
});
}
因此在碰到如下情况时,两者会有很大的不同
<div class="positionRelative">
<table>
<tr>
<td><span>Hello</span></td>
</tr>
</table>
</div>
span.offsetParent为tdtd.offsetParent为tabletr.offsetParent为table$('span').offsetParent()为div$('td').offsetParent()为div$('tr').offsetParent()为div
— 2016/04/20 更新 —