说到offset家族,我们分为三个点来分析:
- offsetParent
- offsetTop、offsetLeft
- offsetWidth、offsetHeight
下面我们逐条分析:
offsetParent
首先我们先看一下官方的定义:
- HTMLElement.offsetParent 是一个只读属性,返回一个指向最近的(指包含层级上的最近)包含该元素的定位元素或者最近的 table,td,th,body元素。当元素的 style.display 设置为 “none” 时,offsetParent 返回 null;
看完概念是不是有点懵,我们一步一步来分析
当元素本身没有定位时
父元素和祖先元素都没有定位时
- 当上一级或者最近的祖先是td,th时,el.offsetParent返回td,th
- 当上一级或者最近的祖先是table时,el.offsetParent返回table
- 当上一级或者最近的祖先没有定位,不是 table,td,th时,el.offsetParent返回body
<body>
<div class="father">
<div class="son"></div>
</div>
<table>
<thead class="thead">
<tr class="trone">
<th class="th">
<span class="span"></span>
</th>
</tr>
</thead>
<tbody>
<tr class="trtwo">
<td class="td">
<a href="#" class="a">学废了</a>
</td>
</tr>
</tbody>
</table>
<script>
console.log(document.querySelector(".span").offsetParent);//th
console.log(document.querySelector(".th").offsetParent);//table
console.log(document.querySelector(".trone").offsetParent);//table
console.log(document.querySelector(".thead").offsetParent);//table
console.log(document.querySelector(".a").offsetParent);//td
console.log(document.querySelector(".td").offsetParent);//table
console.log(document.querySelector(".trtwo").offsetParent);//table
console.log(document.querySelector(".son").offsetParent);//body
console.log(document.querySelector(".father").offsetParent);//body
</script>
看一下打印结果
和上面猜测一样,接下来让我们看一下自身有定位的情况
当元素本身没有定位时,父元素或祖先元素有定位
这里我们先看案例
<body>
<div class="grandpa" style="position: relative;">
<div class="father" style="position: absolute;">
<div class="son"></div>
</div>
</div>
<div class="grandma" style="position: absolute;">
<div class="mama">
<div class="sister"></div>
</div>
</div>
<div class="big" style="position: static;">
<div class="small"></div>
</div>
<div class="more" style="position: fixed;">
<div class="lit"></div>
</div>
<script>
console.log(document.querySelector(".son").offsetParent); //father
console.log(document.querySelector(".father").offsetParent); //grandpa
console.log(document.querySelector(".sister").offsetParent); //grandma
console.log(document.querySelector(".small").offsetParent); //body
console.log(document.querySelector(".lit").offsetParent); //more
</script>
</body>
我们会发现只要在父元素有定位的时候,他会找最近的有定位的父元素的dom元素
但是要注意的是,static除外,向我们上面small的父元素虽然有定位,但是由于定位元素为staic,所以还是指向了body
还需要注意的是:当是table表格的时候有一点不一样,看下面
<table style="position: fixed;">
<thead class="thead" style="position: fixed;">
<tr class="trone">
<th class="th">
<span class="span"></span>
</th>
</tr>
</thead>
</table>
console.log(document.querySelector(".span").offsetParent); //th
console.log(document.querySelector(".trone").offsetParent); //thead
这两个输出结果一个为th,一个为thead;
注意
- 我们会发现上面span最近的有非static的定位元素为thead ,但是还是输出了th
- 但是我们发现trone找到了最近的有非static的定位元素thead
- 当为table时要格外注意,多打印确认结果
当元素本身有定位时
父元素或祖先元素没有定位或者为static时(非table)找到body(不为fixed的时候)
当为table元素的时候需要格外注意
这个时候直接找到body
父元素或祖先元素有非static定位时找最近的有定位的父元素的dom元素(不为fixed的时候)
当元素本身有定位时且为fixed的时候offsetParent为null
<div class="big" style="position: absolute;">
<div class="small" style="position: absolute;"></div>
</div>
<div class="more" style="position: fixed;">
<div class="lit" style="position: static;"></div>
</div>
<div class="mama">
<div class="sister" style="position: absolute;"></div>
</div>
<div class="father" style="position: absolute;">
<div class="son" style="position: fixed;"></div>
</div>
console.log(document.querySelector(".sister").offsetParent); //body
console.log(document.querySelector(".small").offsetParent); //big
console.log(document.querySelector(".lit").offsetParent); //more
console.log(document.querySelector(".son").offsetParent);//null
特殊情况body的offsetParent为null
总结
本篇文章介绍了offsetParent,后续将继续对 offsetTop、offsetLeft
, offsetWidth、offsetHeight做出详细介绍,如果有问题可以在下面评论