元素 offset client scroll 相關屬性簡介

思惟導圖:

一 offset 系列

1.1 定位元素

定位元素(positioned element)是指該元素計算後位置(position)屬性爲 relative, absolute, fixed 或 sticky 的一個元素。同時定位屬性又細分爲如下幾種:javascript

  • 相對定位元素(relatively positioned element): 指該元素計算後位置(position)屬性爲 relative 的元素
  • 絕對定位元素(absolutely positioned element): 指該元素計算後位置(position)屬性爲 absolute 或 fixed 的元素
  • 粘性定位元素(stickily positioned element): 指該元素計算後位置(position)屬性爲 sticky 的元素

對於絕對定位元素(position 屬性爲 absolute 或 fixed 的元素 ), 在未設置 height 和 width 或者爲 auto 的狀況下,容許經過 top bottom left right 來填充容器可用的空間, 只是 top bottom left right 的參考對象不一樣而已;css

1.2 Element.offsetParent

Element.offsetParent 是一個只讀屬性, 返回當前元素最近的一個父級定位元素。同時又有下列幾種特殊狀況:html

  • 若是當前元素沒有父級定位元素,則 offsetParent 爲最近的標準單元格元素( td 元素)
  • 若是當前元素最近也沒有標準單元格元素,則爲 body 元素。(有種說法: 標準模式下爲 offsetParent 爲 html 元素, quirks 模式下可是通過測試好像都是 body 元素)
  • 在 WebKit 爲核心的瀏覽器上,若是元素是隱藏的(style.display='none')或者元素 style.position='fixed',則該元素 offsetParent 爲 null
  • 在IE(9)上只有當元素 style.position='fixed' 時 offsetParent 纔會返回 null, 即便元素 display = 'none' 也是不會影響返回結果

1.3 Element.offsetLeft && Element.offsetTop

Element.offsetLeft 和 Element.offsetTop 是一個只讀屬性,返回當前**元素邊界(border)**相對於 Element.offsetParent 節點的偏移的像素值。java

  • 示意圖:

  • 上圖演示代碼:
<style> #parent{ position: relative; border: 30px solid red; padding: 30px; width: 200px; height: 200px; } #child{ border: 30px solid blue; padding: 30px; margin: 20px; width: 20px; height: 20px; } </style>
<div id="parent">
  <div id="child"></div>
</div>
<script> const dom = document.getElementById('child'); console.log(dom.offsetParent); // <div id="parent"></div> console.log(dom.offsetTop); // 50 </script>
複製代碼

1.4 Element.offsetWidth && Element.offsetHeight

Element.offsetWidth 和 Element.offsetHeight 是一個只讀屬性,返回一個元素佈局的寬高(元素佈局包括: border、滾動條、padidng、內容塊), 該屬性返回的值爲一個四捨五入的整數瀏覽器

  • 示意圖:

  • 上圖演示代碼:
<style> #parent{ margin: 10px; border: 20px solid red; padding: 20px; width: 100px; height: 100px; overflow: scroll; } #child{ width: 100%; height: 100%; background: #eee; } </style>

<div id="parent">
  <div id="child"></div>
</div>
<script> const dom = document.getElementById('parent'); console.log(dom.offsetParent); // <body></body> console.log(dom.offsetHeight); // 180 console.log(dom.offsetWidth) // 180 </script>
複製代碼

1.5 內聯元素下的特殊行爲

上文關於 Element offset 系列屬性的描述都是針對塊級元素進行的,至於內聯元素又有必定的區別:dom

  • 示意圖:

  • 上圖演示代碼:
<style> #parent{ position: relative; width: 200px; border: 10px solid red; } #Placeholder{ display: inline-block; width: 100px; } #child{ border: 10px solid blue; padding: 10px; } </style>
<div id="parent">
    <span id="Placeholder">佔位元素</span>
    <span id="child">
      要計算的元素要計算的元素要計算的元素
    </span>
  </div>
<script> const dom = document.getElementById('child'); console.log(dom.offsetParent); console.log(dom.offsetTop); // -12 console.log(dom.offsetLeft); // 104 console.log(dom.offsetWidth); // 192 console.log(dom.offsetHeight); // 102 </script>
複製代碼

二 client 系列

  • Element.clientTop 和 Element.clientLeft 獲取可視區域的偏移值(實際上就等於元素上下 border 值) 四捨五入(整數)後的結果;
  • Element.clientWidth 和 Element.clientHeight 獲取可視區域(padding + 元素內容區域的寬高,不包含滾動條)的寬高
  • 示意圖:

  • 上圖演示代碼:
<style> #parent{ margin: 10px; border: 20.5px solid red; padding: 20px; width: 100px; height: 100px; overflow: scroll; } #child{ width: 100%; height: 100%; background: #eee; } </style>
<div id="parent">
  <div id="child"></div>
</div>
<script> const dom = document.getElementById('parent'); console.log(dom.clientTop); // 21 console.log(dom.clientLeft); // 21 console.log(dom.clientWidth); // 125 console.log(dom.clientHeight); // 125 </script>
複製代碼

三 scroll 系列(用於對可滾動元素進行求值)

3.1 Element.scrollTop && Element.scrollLeft(可寫)

Element.scrollTop 和 Element.scrollLeft 用於獲取或設置元素被捲起的寬高(子元素頂部或左側到當前元素可視區域頂部或左側的距離)佈局

  • 示意圖:以 scrollTop 爲例

  • 上圖演示代碼:
<style> #parent{ width: 200px; height: 200px; padding: 50px; background: #eee; overflow: auto; } #child { height: 400px; margin: 50px; padding: 50px; width: 20px; background: #ccc; } </style>
<body>
  <div id="parent">
    <div id="child"></div>
  </div>
</body>
<script> window.onload = () => { const dom = document.getElementById('parent'); dom.onscroll= () => { console.log(dom.scrollTop); } } </script>
複製代碼
  • 補充:
    • 對於不可滾動的元素 Element.scrollTop 和 Element.scrollLeft 值爲 0
    • 若是給 scrollTop(scrollLeft) 設置的值小於0,那麼 scrollTop(scrollLeft) 的值將變爲0。
    • 若是給 scrollTop(scrollLeft) 設置的值大於元素內容最大寬度,那麼 scrollTop(scrollLeft) 的值將被設爲元素最大寬度(高度)。

3.2 Element.scrollWidth && Element.scrollHeight

  • Element.scrollWidth 和 Element.scrollHeight 是隻讀屬性, 表示元素可滾動區域的寬高; 實際上又等於 clientHeight/clientWidth + 未顯示在屏幕中內容的寬高;
  • 它們的值等於元素在不使用水平滾動條的狀況下適合視口中的全部內容所需的最小寬度。
  • 測量方式與 clientWidth(clientHeight) 相同:它包含元素的內邊距,但不包括邊框,外邊距或垂直滾動條(若是存在)。 它還能夠包括僞元素的寬度,例如::before或::after。
  • 若是元素的內容能夠適合而不須要水平滾動條,則其 scrollWidth 等於 clientWidth; (最小值爲元素的可視區域寬高: clientWidth (clientHeight))
  • 示意圖:以 scrollHeight 爲例

  • 上圖演示代碼:
<style> #parent{ width: 200px; height: 200px; padding: 50px; background: #eee; overflow: auto; } #child { height: 400px; margin: 50px; padding: 50px; width: 20px; background: #ccc; } </style>

<body>
  <div id="parent">
    <div id="child"></div>
  </div>
</body>
<script> window.onload = () => { const dom = document.getElementById('parent'); console.log(dom.scrollHeight); // 700 } </script>
複製代碼

補充:測試

  • 雖然 scrollWidth 計算方式和 scrollHeight 是同樣的, 可是若是在可滾動元素中其子元素使用了 margin-right 則會發生 margin 塌陷等問題, 這時實際計算出的 scrollWidth 會有所不一樣
相關文章
相關標籤/搜索