详细 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盒模型中,其盒子大小的计算方式也是一样.

下面我们来看看 offsetTopoffsetLeft在了解它们两之前,先来了解下 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呈现方式一样的.

原文链接:segmentfault.com

上一篇:google-maps-infobox
下一篇:浏览器是如何工作的?(How browser work?)

相关推荐

官方社区

扫码加入 JavaScript 社区