本文詳細介紹實用方法 getBoundingClientRect(),以及 left、top、right、bottom、width、height 等相關屬性,並教你如何搭配 window.pageXOffset 和 window.pageYOffset 將相對位置轉換為絕對位置。
目錄
getBoundingClientRect() 的使用方法
如果要取得元素 elem
「相對於視窗」的座標,我們可以使用 elem.getBoundingClientRect()
這個方法。他會量測元素包含 border 的大小,並回傳一個 DOMRect 物件,其中包含了 x
/y
/width
/height
/top
/right
/bottom
/left
等屬性。
getBoundingClientRect() 屬性說明 (left, top, right, bottom, width, height)
x
/left
:elem
左上角的 x 座標y
/top
:elem
左上角的 y 座標width
:elem
的寬度,通常等於offsetWidth
height
:elem
的高度,通常等於offsetHeight
right
:elem
右下角的 x 座標bottom
:elem
右下角的 y 座標
可參考下圖:
這些屬性有一些需要注意的事項:
- 座標可能是負值,例如:當元素的頂端超出視窗頂端的範圍時,
top
就會變成負的。 - IE 跟 Edge 沒有
x
跟y
屬性,但可用left
跟top
。 rect.width
跟rect.height
可能有小數,而offsetWidth
/offsetHeight
會回傳整數。如果需要精確的大小則需要用到 getBoundingClientRect()。- 一般來說
rect.width
等於elem.offsetWidth
,但elem.offsetWidth
是 layout 的大小,而width
是實際 rendering 的大小。比如說用了transform: scale(0.5)
,寬度 200px 的元素在空間上佔據的位置一樣是 200px (offsetWidth
),但是視覺實際看到只有 100px (rect.width
)。可以看以下的例子:
See the Pen RwNGJoy by Shubo Chao (@shubochao) on CodePen.
想了解更多 offsetWidth
/offsetHeight
細節可以看這篇:
如何用 window.pageXOffset 和 window.pageYOffset 算出絕對位置
很多時候我們需要的是「絕對位置」,也就是元素相對於「文件左上角」的座標,可惜的是瀏覽器並沒有提供一個原生的值可以讓我們使用。
幸好有個很簡單的公式可以幫助我們很方便地計算出絕對位置,那就是「絕對位置座標系和視窗座標系之間的差距」等於捲軸已捲動的長度,也就是 [window.pageXOffset, window.pageYOffset]
。
所以,絕對位置的計算方式如下:
const x = window.pageXOffset + rect.left;
const y = window.pageYOffset + rect.top;
即使元素在視窗的範圍以外,上面的等式也成立,因為 top/left
是視窗座標系的座標,當超出視窗範圍時會變負值。
想知道更多 pageXOffset
/pageYOffset
的細節,可以看這篇: