参考博文:
一、偏移量(offset dimension)简介
- 包括元素在屏幕上占用的所有可见的空间。
- 元素的可见大小由其高度、宽度决定,包括所有内边距、滚动条和边框大小(注意,不包括外边距)。
二、定位父级(offsetParent)
2.1 定义
定位父级:与当前元素最近的经过定位(
position
不等于static
)的父级元素。
2.2 定位父级分类
- 1.元素自身有
fixed
定位,offsetParent
的结果为null
。- 当元素自身有
fixed
固定定位时,我们知道固定定位的元素相对于视口进行定位,此时没有定位父级,offsetParent
的结果为null。
- 当元素自身有
<div class="pub" style="position: fixed" id="div1"></div>
<script>
console.log(document.getElementById('div1').offsetParent); // null
</script>
- 2.元素自身无
fixed
定位,且父级元素都未经过定位,offsetParent
的结果为body
。
<div class="pub" id="div2"></div>
<script>
console.log(document.getElementById('div2').offsetParent); // body
</script>
- 3.元素自身无
fixed
定位,且父级元素存在经过定位的元素,offsetParent
的结果为离自身元素最近的经过定位的父级元素。
<div class="pub" style="position: relative" id="outer">
<div id="inner"></div>
</div>
<script>
console.log(document.getElementById('inner').offsetParent); // outer div
</script>
- 4.
body
元素的offsetParent
是null
。
三、 偏移量拥有的值
offsetHeight
:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上下边框高度、上下内边距。
- 即:
offsetHeight = border-top-width + padding-top + height + padding-bottom + border-bottom-width
offsetWidth
:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见的)垂 直滚动条的宽度、左右边框宽度、左右内边距。
- 即:
offsetWidth = border-left-width + padding-left + width + padding-right + border-right-width;
<div id="test" style="width:100px; height:100px; padding:10px; margin:10px; border:1px solid black;"></div>
<script>
//122=1+10+100+10+1
console.log(test.offsetWidth);
console.log(test.offsetHeight);
</script>
offsetLeft
:元素的左外边框至offsetParent
元素的左内边框之间的像素距离。offsetTop
:元素的上外边框至offsetParent
元素的上内边框之间的像素距离。
<div id="out" style="padding: 5px;position: relative;background-color: pink;margin: 6px;border:1px solid black">
<div id="test" style="width:100px; height:100px; margin:10px;background-color:green;"></div>
</div>
<script>
//15=test.marginTop(10) + out.paddingTop(5)
console.log(test.offsetTop);
//15=test.marginLeft(10) + out.paddingLeft(5)
console.log(test.offsetLeft);
</script>
- 第一条红线:
offsetParent
的做内边框 - 第二条红线:元素的左外边框
四、页面偏移
- 要知道某个元素在页面上的偏移量,将这个元素的
offsetLeft
和offsetTop
与其offsetParent
的相同属性相加, 并加上offsetParent
的相应方向的边框,如此循环直到根元素,就可以得到元素到页面的偏移量
function getElementLeft(element){
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while(current != null){
actualLeft += current.offsetLeft + current.clientLeft;
current = current.offsetParent;
}
return actualLeft + 'px';
}
function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while(current != null){
actualTop += current.offsetTop + current.clientTop;
current = current.offsetParent;
}
return actualTop + 'px';
}
<div style="padding: 20px;border:1px solid black;position:absolute;">
<div id="test" style="width:100px; height:100px; margin:10px;"></div>
</div>
<script>
//其他浏览器返回31(10+20+1),而IE7-浏览器返回21((20和10的较大值)+1)
console.log(getElementTop(test));
//所有浏览器返回31(10+20+1)
console.log(getElementLeft(test));
</script>
五、注意事项
- 所有偏移量属性都是只读的
- 如果给元素设置了
display:none
,则它的偏移量属性都为0- 每次访问偏移量属性都需要重新计算 注意:重复访问偏移量属性需要耗费大量的性能,所以要尽量避免重复访问这些属性。如果需要重复访问,则把它们的值保存在变量中,以提高性能