你的浏览器不支持canvas

Enjoy life!

javascript - 偏移量

Date: Author: JM

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

参考博文:

一、偏移量(offset dimension)简介

relationship-map

  • 包括元素在屏幕上占用的所有可见的空间。
  • 元素的可见大小由其高度、宽度决定,包括所有内边距、滚动条和边框大小(注意,不包括外边距)。

二、定位父级(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元素的offsetParentnull

三、 偏移量拥有的值

  • 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的做内边框
  • 第二条红线:元素的左外边框

relationship-map

四、页面偏移

  • 要知道某个元素在页面上的偏移量,将这个元素的offsetLeftoffsetTop与其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>

五、注意事项

  1. 所有偏移量属性都是只读的
  2. 如果给元素设置了display:none,则它的偏移量属性都为0
  3. 每次访问偏移量属性都需要重新计算 注意:重复访问偏移量属性需要耗费大量的性能,所以要尽量避免重复访问这些属性。如果需要重复访问,则把它们的值保存在变量中,以提高性能

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。