offsetWidth、Height、Top、Left、offsetParent
前者计算元素的大小, 后者两者返回元素相对 offsetParent 元素的偏移量.
offsetWidth
返回一个元素的布局宽度;
计算方式:
content width(CSS 设定的 width) + padding + border + scrollBarWidth 如果存在垂直滚动条(scrollbar)
offsetHeight
返回一个元素的布局高度;
计算方式:
content height(CSS 设定的 height) + padding + border + scrollbarHeight 如果存在水平滚动条(scrollbar)
大家看到 content + padding + border
是否很熟悉, 在盒子模型中提及, 在 IE 盒模型中, 其盒子大小的计算方式也是一样.
下面我们来看看 offsetTop
、offsetLeft
在了解它们两之前, 先来了解下 offsetParent
offsetParent
可以理解为偏移的基准, 这有点类似定位属性中(absolute 以最近的祖先元素容器且设置了定位属性的元素来进行位置偏移.)
什么样的元素为 offsetParent
?
- 拥有定位属性的元素
- dispaly 为 table 或 table cell
- 默认情况下根元素
依次从内往外找, 如果没有, 默认就是已根元素作为 offsetParent
也就是偏移的基准.
当元素设置属性 display: none
, 则它相应的 offsetParent
属性返回值为 null
.
注意:
如果元素为隐藏的(该元素或其祖先元素的 style.display 为 “none”), 或者该元素的 style.position 被设为 “fixed”, 则该 offsetParent
属性返回 null。在 IE 9 中 display:none 无影响.
offsetLeft
返回一个元素 (border 边框) 到 offsetParent 元素左边界 (边界可能为边框或内边距) 的距离.
offsetTop
返回一个元素 (border 边框) 到 offsetParent 元素上边界 (边界可能为边框或内边距) 的距离.
下面我们来实战一下吧
<style>
html {
margin: 10px;
padding: 10px;
border: 1px solid blue;
}
body {
margin: 10px;
padding: 10px;
border: 1px solid red;
}
.contanier {
display: inline-block;
background-color: #F7EED6;
}
.box {
width: 200px;
height: 200px;
margin: 10px;
padding: 5px;
border: 5px solid black;
background-color: #ccc;
}
</style>
<div class="contanier">
<div class="box">
</div>
</div>
<script>
var ele = document.querySelector(".box");
ele.offsetLeft; // IE\Edge 52 Chrome 42 Firefix 41
ele.offsetTop; // IE\Edge 52 Chrome 42 Firefix 41
ele.offsetWidth; // 200 + 5 * 2 + 5 * 2 = 220
ele.offsetHeight; // 200 + 5 * 2 + 5 * 2 = 220
ele.offsetParent === document.documentElement // false
ele.offsetParent === document.body // true
</script>
这里分两种情况:
当不存在定位属性时:IE、Edge、Chrome、Firefix 呈现值不一样:
IE、Edge
中:
offsetLeft = box margin + body padding + body border + body margin + html padding + html border + html margin
可以理解为相对于视口的偏移
Chrome
中:
offsetLeft = box margin + body padding + body border + html padding + html border
可以理解为相对于 HTML 元素边框(包含边框)
Firefix
中:
offsetLeft = box margin + body padding + body border + html padding
可以理解为相对于 HTML 元素边框(不包含边框).
其实这里我是有疑问的, 为什么没有指定定位等属性情况下, ele.offsetParent === document.body
却为 true
, 从结果来看实际偏移计算又是依据 HTML 或视口来的 , 如果有知道可以告知下.
当存在定位属性时, 更改下 HTML 代码, 如下:
<style>
html {
position: relative;
margin: 10px;
padding: 10px;
border: 1px solid blue;
}
</style>
IE、Edge、Firefox
中:
offsetLeft = box margin + body padding + body border + html padding
可以理解为相对于 HTML 边框偏移量(不包含边框)
Chrome
中:
offsetLeft = box margin + body padding + body border + html padding + html border
可以理解为相对于 HTML 边框偏移量(含边框)
如果不存在边框的话, 在 IE、Edge、Chrome、Firefox 呈现方式一样的.