JS offset系列簡明教程

本文自出“阿敏其人”技術博客,轉載請取得本人同意。


一、offset團隊的成員

說起,offset,單詞本身是偏移,補償和位移的意思。
JS中有一些offset方法/屬性屬性用於獲取元素尺寸。

打開像泰坦尼克一樣的經典的北少林失傳經典——W3c Element元素大全,我們發現,關於offset,大概有如下一些屬性:

屬性 解釋
element.offsetHeight 返回元素的高度。
element.offsetWidth 返回元素的寬度。
element.offsetLeft 返回元素的水平偏移位置。
element.offsetTop 返回元素的垂直偏移位置。
element.offsetParent 返回元素的偏移容器。

嗯,大道至簡,言簡意賅,簡單到都不知道怎麼區分了。
不過,還是爲芸芸衆生指明瞭大的方向。那就是,寬高左上父類

理解offset系列的時候,我們經常會和style樣式的類似屬性對對比。

注意:
==offset系列屬性都是 只讀 的。==
==style.top、style.height之類的style系列的屬性是 可讀可寫 的。==

image.png

二、offsetHeight和offsetWidth

這對大兄弟,就是經典的寬和高了。
他們非常類似,我們以 offsetWidth 例子展開描述。

說起寬度,遙想過去,我們自然會想起css裏面的style.width,既然有這個鬼東西存在了,那麼還要offsetWidth來幹嘛,字母比較長顯得比較牛逼嗎?

顯然不是,因爲style.width有一定的弊端。

css的style.width的弊端

style.width只有在行內式的時候纔可以獲取到寬度。

offsetWidth如何計算寬度

計算方式

offsetWidth = width + border + padding

也就是,margin我不要,其他我都算。

栗子,style.width和offsetWidth

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        body{
            background-color: #6C6C6C;
            margin:0;
            padding:0
        }
        #box1{
            width: 10px;
            height: 10px;
            padding: 20px;
            margin: 30px;
            border: 3px solid red;
        }
    </style>

</head>
<body>
<div id="box1"></div>
<div id="box2" style="width: 30px; height: 30px; border: 1px solid blue"></div>
</body>
<script>
    var box1 = document.getElementById("box1");
    console.log("box1 style.width: "+box1.style.width); // 輸出空  style.width 只能得到行內式
    console.log("box1.offsetWidth: "+box1.offsetWidth); // 輸出 56
    console.log("box1.offsetHeight: "+box1.offsetHeight); // 輸出 56
    console.log("===");
    console.log("box2 style.width: "+box2.style.width); // 輸出 30px
    console.log("box1.offsetWidth: "+box2.offsetWidth); // 輸出 32
    console.log("box1.offsetHeight: "+box2.offsetHeight);  // 32
</script>
</html>

.
.
效果:

image.png

.
.

offsetWidth小結圖

image.png

.
.

三、offsetLeft和offsetTop

我們的知道,在計算機的世界裏,不上講究上下左右,而是上左,下右之類的。
有了寬高,加上top和left,就可以框定一個確定一個東西的大小和位置。

說起offset的left和top,我們接着和style較勁,比如style.left。

style.left的弊端

只有在行內式定位的元素纔有style.left。
(只有行內樣式的css的才能取到style.left的值)

offsetLeft的計算

offsetLeft:找到離元素最近的已經定位的父元素或祖先元素定位;如果沒有,就根據根節點body定位,然後獲取其left值。

  • 返回距離父元素(最近的帶有定位)左邊的位置(可以是間接父級)
  • 如果父元素都沒有定位則以body 爲準
  • ==offsetLeft 從父元素的padding 開始算,(不是父元素的border)==

offsetLeft和offsetTop類似,我們以offsetLeft爲例子展開描述,和style.left作對比。

例子,offsetLeft 和 style.left

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        body{
            margin:0;
            padding:0
        }
        .grand{
            width: 300px;
            height: 300px;
            border: 7px solid gray;
            padding: 18px;
            background-color: red;
            position: relative;
        }
        .father{
            width: 200px;
            height: 200px;
            background-color: green;
            margin: 50px;
        }
        #son{
            width: 100px;
            height: 100px;
            background-color: blue;
            margin: 50px;
        }
        /*這樣依然取不到style.left的值*/
        /*#son2{*/
            /*width: 100px;*/
            /*height: 100px;*/
            /*background-color: orange;*/
            /*margin: 50px;*/
            /*position: absolute;*/
            /*top: 6px;*/
            /*left: 6px;*/
        /*}*/

    </style>

</head>

<body>
<div class="grand">
    <div class="father">
        <div id="son"></div>
        <div id="son2" style="width: 100px; height: 100px; background-color: orange; margin: 50px;
            position: absolute; top: 6px; left: 6px">

        </div>
    </div>
</div>
</body>

<script>
    var son = document.getElementById("son");
    var son2 = document.getElementById("son2");
    console.log("son.offsetLeft: "+son.offsetLeft); // son.offsetLeft: 118
    console.log("son.style.left: "+son.style.left); // son.offsetLeft: 118

    console.log("son2.offsetLeft: "+son2.offsetLeft); // son2.offsetLeft: 56
    console.log("son2.style.left: "+son2.style.left); // son2.style.left: 6px   注意:style.left輸出值是帶px(如果有值)

</script>
</html>

可以看出:
確實是需要內行樣式時,style.left才能取出時。
style.left取出的是還有px後綴。
style.left取出的值,是跟自己作比較,而不是跟父元素。

son.offsetLeft顯然是跟“父元素”作比較的。

offsetLeft 和 offsetTop 小結圖

image-2.png

.
.

四、offsetParent 獲取父元素

特點

  • 1、元素自身有fixed定位,offsetParent的結果爲null
    • firefox並沒有考慮固定定位的問題,返回<body>,其他瀏覽器都返回null
    • 當元素自身有fixed固定定位時,我們知道固定定位的元素相對於視口進行定位,
      此時沒有定位父級,offsetParent的結果爲null
  • 2、如果找到存在定位的父元素,offsetParent返回該父元素
  • 3、如果沒有任何一個父元素(不斷向上,找到爲止)存在定位,offsetParent爲body
  • 4、<body>元素的parentNode是null

例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        /*如果自身爲fixed,那麼offsetParent爲null*/
        /*.test{*/
            /*position: fixed;*/
        /*}*/

        .div0{
            position:absolute;
        }


        .div1{
            position: relative;
        }

    </style>

</head>

<body>
<div id="div0" class="div0">
    <div id="div1" class="div1">
        <div id="test" class="test"></div>
    </div>
</div>
</body>

<script>
    var test = document.getElementById("test");
    console.log(test.offsetParent);
    console.log(test.offsetParent.id);
    console.log(test.offsetParent.tagName);
</script>
</html>

運行結果:

image.png

.
.

offsetParent 小結圖

image-3.png

總結圖

image-4.png

同系列相關文章:

JS client系列簡明教程
JS scroll系列簡明教程

本文完。


參考:
深入理解定位父級offsetParent及偏移大小

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章