JavaScript之深入理解偏移量offset

前言

偏移量offset是JavaScript中非常重要的一个概念,涉及偏移量的主要属性有:offsetLeftoffsetTopoffsetWidthoffsetHeight。当然,还有一个参照属性---定位父级offsetParent。本文将详细介绍这些内容。

当前元素与定位父级的关系图:



定位父级offsetParent

在理解偏移大小之前,首先要理解的就是定位父级offsetParent,之所以翻译成定位父级,那是因为它跟定位有关系。


定位父级offsetParent的定义:“离”当前元素“最近”的 经过定位的(position不等于static)的父级元素。也就是说,它是一个有position属性的父级元素,当前元素是它的子元素。我们知道,元素查找是逐级向上查找的。

<div id="test" >
  <div id="test1" style="position: relative">
    <div id="test2"></div>
  </div>
</div>

此例#test2的定位父级是#test1,在这个例子中,#test1是唯一的一个有position属性的,所以只有它离#test2最近。


<div id="test" style="position: relative;">
  <div id="test1" style="position: relative;">
    <div id="test2"></div>
  </div>
</div>

在此例中,#test2的定位父级依然是#test1,尽管#test和#test1都有position属性,但#test1离#test2最近。


<div id="test" style="position: relative;">
  <div id="test1">
    <div id="test2"></div>
  </div>
</div>

在这个例子中,#test2的定位父级是#test,因为#test有position属性且离#test2最近。



元素自身有fixed定位时,offsetParent返回null。

当元素自身是固定定位时,固定定位是相对于视口定位的,此时没有父级定位,offsetParent返回null。

<!docutype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>深入理解偏移量offset</title>
	<style>
	  
	</style>
  </head>
  <body>
  
    <div id="test">
	  <div id="test1" style="position: relative;">
	    <div id="test2" style="position: fixed;"></div>
	  </div>
	</div>
  
  <script>
    
      var test2 = document.getElementById("test2");
	  
	  console.log(test2.offsetParent); //null
    
  </script>
  </body>
</html>



元素自身无fixed定位,且父级元素未经过定位,offsetParent返回<body>

<!docutype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>深入理解偏移量offset</title>
	<style>
	  
	</style>
  </head>
  <body>
  
    <div id="test">
	  <div id="test1">
	    <div id="test2"></div>
	  </div>
	</div>
  
  <script>
    
      var test2 = document.getElementById("test2");
	  
      console.log(test2.offsetParent); //<body></body>
    
  </script>
  </body>
</html>


元素自身无fixed定位,且父级元素存在经过定位的元素,offsetParent返回 离自身元素最近的且经过定位的父级元素。

<!docutype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>深入理解偏移量offset</title>
	<style>
	  
	</style>
  </head>
  <body>
  
    <div id="test" style="position: relative">
	  <div id="test1" style="position: relative">
	    <div id="test2"></div>
	  </div>
	</div>
  
  <script>
    
      var test2 = document.getElementById("test2");
	  
      console.log(test2.offsetParent); //<div id="test1"></div>
    
  </script>
  </body>
</html>


<body>的offsetParent返回null

console.log(document.body.offsetParent); //null


偏移量

偏移量包含offsetLeft、offsetTop、offsetWidth、offsetHeight这四个属性。


offsetWidth

该属性表示元素在水平方向占用的空间大小。无单位(以像素计)。

offsetWidth = border-left-width + padding-left + width + padding-right + border-right-width

offsetHeight

该属性表示元素在垂直方向占用的空间大小。无单位(以像素计)。

offsetHeight = border-top-height + padding-top + height+ padding-top + border-top-height

offsetWidth和offsetHeight在页面中的计算:

<!docutype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>深入理解偏移量offset</title>
    <style>
	  
    </style>
  </head>
  <body>

    <div id="test" style="position: relative">
      <div id="test1" style="position: relative">
      <div id="test2" style="width: 100; height: 100; margin: 10; padding: 10; border: 1px solid red"></div>
      </div>
    </div>
  
  <script>
    
      var test2 = document.getElementById("test2");
	  
      //122 = 10 + 10 + 100 +2
      console.log(test2.offsetWidth); //122
      //122 = 10 + 10 + 100 +2
      console.log(test2.offsetHeight); //122
      
    
  </script>
  </body>
</html>


注意:如果存在滚动条,offsetWidth也包括垂直滚动条的宽度,offsetHeight也包括水平滚动条的高度。


offsetTop

offsetTop表示元素的上外边框offsetParent上内边框之间的像素距离。


offsetLeft

offsetLeft表示元素的左外边框offsetParent左内边框之间的像素距离。


<!docutype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>深入理解偏移量offset</title>
    <style>
	  
    </style>
  </head>
  <body>
  
    
    <div id="test1" style="position: relative;width: 200; height: 200; margin: 10; padding: 10; border: 1px solid red ">
      <div id="test2" style="width: 100; height: 100; margin: 10; padding: 10; border: 1px solid red"></div>
    </div>
	
  
  <script>
    
      var test2 = document.getElementById("test2");
	  
      //20 = test2.marginTop(10) + test1.paddingTop(10)
      console.log(test2.offsetTop); //20
	  
      //20 = test2.marginLeft(10) + test2.marginLeft(10)
      console.log(test2.offsetLeft); //20
	  
	  
  </script>
  </body>
</html>



注意事项


每个偏移量都只是可读的。也就是说不能通过赋值来修改偏移量。

<!docutype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>深入理解偏移量offset</title>
    <style>
	  
    </style>
  </head>
  <body>
  
    
    <div id="test1" style="position: relative;width: 200; height: 200; margin: 10; padding: 10; border: 1px solid red ">
      <div id="test2" style="width: 100; height: 100; margin: 10; padding: 10; border: 1px solid red"></div>
    </div>
	
  
  <script>
    
      var test2 = document.getElementById("test2");
	  
      //20 = test2.marginTop(10) + test1.paddingTop(10)
      console.log(test2.offsetTop); //20
      
      test2.offsetTop = 30;//尝试将偏移量修改为30
      console.log(test2.offsetTop); //20 只是可读的,不能修改。
	  
      //20 = test2.marginLeft(10) + test2.marginLeft(10)
      console.log(test2.offsetLeft); //20
	  
	  
  </script>
  </body>
</html>

上述例子中,想通过赋值运算来修改偏移量,结果是不能修改的,只是可读的。



如果给元素设置了dispaly: none;那么这个元素的偏移量为0。

<!docutype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>深入理解偏移量offset</title>
    <style>
	  
    </style>
  </head>
  <body>
  
    
    <div id="test1" style="position: relative;width: 200; height: 200; margin: 10; padding: 10; border: 1px solid red ">
      <div id="test2" style="display: none; width: 100; height: 100; margin: 10; padding: 10; border: 1px solid red"></div>
    </div>
	
  
  <script>
    
      var test2 = document.getElementById("test2");
	  
      //20 = test2.marginTop(10) + test1.paddingTop(10)
      console.log(test2.offsetTop); //0
      
      test2.offsetTop = 30;//尝试将偏移量修改为30
      console.log(test2.offsetTop); //0 只是可读的,不能修改。
	  
      //20 = test2.marginLeft(10) + test2.marginLeft(10)
      console.log(test2.offsetLeft); //0
	  
	  
  </script>
  </body>
</html>



每次访问偏移量,都需要重新计算,这是一个很耗性能的工作,所以要尽量重复访问这些偏移量。如果需要访问它们,将它们保存在变量中。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值