内容简介:element.offsetParent为包含element的祖先元素中,层级最近的定位元素。 也就是说,offsetParent必须满足三个条件:打印box元素的offsetParent:由此可见,box祖先元素中存在:
element.offsetParent为包含element的祖先元素中,层级最近的定位元素。 也就是说,offsetParent必须满足三个条件:
- 是element的祖先元素
- 最靠近element
- 是定位元素,即position属性不为static
<div class="position-outer" style="position: relative;"> <div class="position" style="postion: relative;"> <div class="not-position"> <div class="box"> </div> </div> </div> </div> 复制代码
打印box元素的offsetParent:
由此可见,box祖先元素中存在:
- 层级为3的定位元素 position-outer
- 层级为2的定位元素 position-inner
- 层级为1的非定位元素 not-position
position-inner是同时满足层级最近和定位两个条件的。
祖先元素中不存在定位元素
<div class="box"></div> 复制代码
webkit内核、Firefox下的特殊情况
- element自身的display属性为none
<div class="position-outer" style="position: relative;"> <div class="position" style="postion: relative;"> <div class="not-position"> <div class="box" style="display: none;"> <!-- 注意这里! --> </div> </div> </div> </div> 复制代码
- element自身的position属性为fixed
<div class="position-outer" style="position: relative;"> <div class="position" style="postion: relative;"> <div class="not-position"> <div class="box" style="position: fixed;"> <!-- 注意这里! --> </div> </div> </div> </div> 复制代码
element.offsetWidth / element.offsetHeight
定义
offsetWidth = content + (垂直滚动条的宽度) + padding + border
- 无滚动条情况下
<div class="box" style=""> </div> 复制代码
.box { width: 200px; height: 100px; padding: 20px; border: 12px solid red; margin: 25px; } 复制代码
打印element.offsetWidth:
offsetWidth = 200(content) + 20 * 2(padding) + 12 * 2(border) = 264
- 有滚动条情况下
可以看到,滚动条包含在padding中,因此,offsetWidth与在无滚动条情况下,大小不变。
element.offsetLeft / element.offsetTop
定义
element左上角相对于offsetParent左边界的偏移值。
有个疑问? element的左上角 与 offsetParent的左边界如何定义?是content-box、padding-box还是margin-box?
<div class="position"> <div class="box"> </div> </div> 复制代码
.position { position: relative; top: 0; left: 0; width: 400px; height: 200px; padding: 35px; border: 15px solid purple; } .box { width: 200px; height: 100px; padding: 20px; border: 12px solid red; margin: 25px; } 复制代码
很明显,box的offsetParent为postion
打印box.offsetLeft和box.offsetTop:
在文档流中,box的整个margin-box是在position的content-box中的,由此可猜测:
box.offsetLeft = position.paddingLeft + box.marginleft = 35 + 25 = 60
真的是这样吗?其实并没有那么简单,需要分两种情况讨论:
element在正常文档流中
element.offsetLeft是指element的border-box左上角相对offsetParent的content-box的偏移量
由于position: relative的元素并没有脱离文档流,因此,也需要加入到offseLeft/offsetTop的计算中
修改box css属性:
.box { position: relative; /* 新增的 */ top: 31px; /* 新增的 */ left: 31px; /* 新增的 */ width: 200px; height: 100px; padding: 20px; border: 12px solid red; margin: 25px; } 复制代码
再次打印box.offsetLeft和box.offsetTop:
两者的值都增加了31,也就是top和left属性对应的值,由此更新计算公式:
element.offsetLeft = offsetParent.paddingLeft + element.left + element.marginLeft
但是,以上都是在最简单的情况下计算的,即element与element.offsetParent之间没有其它层级的元素存在!
我们在element与element.offsetParent之间再插入一个元素:
<div class="position"> <div class="middle"> <!-- 新增的 --> <div class="box"> </div> </div> </div> 复制代码
.parent { width: 30px; height: 150px; padding: 11px; border: 12px solid pink; margin-left: 13px; } 复制代码
打印box.offsetLeft和box.offsetTop:
两者的值又变化了!相比上次又增加了36,正好是parent的marginLeft、borderLeft 、paddingLeft之和,11 + 12 + 13 = 36,由此得到最终的计算公式:
element.offsetLeft = offsetParent.paddingLeft + element.left + element.marginLeft + (element与element.offsetParent之间所有 在正常文档流且position属性不为relative的元素 marginLeft、borderLeft、paddingLeft之和)
element与element.offsetParent之间存在浮动元素
现在,我们让parent向右浮动:
.parent { float: right; width: 30px; height: 150px; padding: 11px; border: 12px solid pink; margin-left: 13px; } 复制代码
打印box.offsetLeft和box.offsetTop:
这次只有box.offsetLeft变化了,而且也可以猜测到是由于parent的右浮,box是其子元素,一起右浮,导致box.offsetLeft变化的。
这下要怎么计算?难道还要算浮动的距离吗?
并不需要!只要借助parent就能计算!仔细想想,element与element.offsetParent一定是没有浮动元素的,那么对于parent,其offsetParent也就是box的offsetParent,即postition。
我们打印下parent.offsetleft:
再计算box到parent之间的偏移量: box.left + box.marginLeft + parent.paddingLeft + parent.borderLeft + parent.marginLeft = 31 + 25 + 11 + 12 + 13 = 92
76 + 92 = 168,与box.offsetLeft一致,这也说明我们的计算公式是正确的!
element脱离文档流
也就是说element的display属性为absolute或fixed,由于fixed会导致offsetParent为null,所以我们将box的display设置为absolute:
<div class="position"> <div class="box"> </div> </div> 复制代码
.box { position: absolute; /* 新增的 */ top: 31px; left: 31px; width: 200px; height: 100px; padding: 20px; border: 12px solid red; margin: 25px; } .position { position: relative; top: 0; left: 0; width: 400px; height: 200px; padding: 35px; border: 15px solid purple; } 复制代码
打印box.offsetLeft和box.offsetTop:
我们知道,display属性为absolute或fixed的元素,是相对于包含块的padding-box定位的,因此在计算offsetLeft时,就不需要考虑offsetParent的paddingLeft了。
并且,element是脱离文档流的,也就是说,除了element.offsetParent,不再与其它任何元素产生联系,也就不需要再考虑element与element.offsetParent之间的任何元素了。
因此,计算公式非常简单:
element.offsetLeft = element.left + element.marginLeft
以上所述就是小编给大家介绍的《offsetParent、offsetLeft/offsetTop深度剖析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java Web开发实例大全(基础卷)
软件开发技术联盟 / 清华大学出版社 / 2016-1 / 128.00
《Java Web开发实例大全(基础卷)》筛选、汇集了Java Web开发从基础知识到高级应用各个层面约600个实例及源代码,每个实例按实例说明、关键技术、设计过程、详尽注释、秘笈心法的顺序进行了分析解读。全书分为6篇23章,主要内容有开发环境搭建、Java语言基础、HTML/CSS技术、JSP基础与内置对象、JavaBean技术、Servlet技术、过滤器与监听器技术、JSTL标签库、JavaS......一起来看看 《Java Web开发实例大全(基础卷)》 这本书的介绍吧!