JS中獲取 DOM 元素的絕對位置實例詳解
在操作頁面滾動和動畫時經(jīng)常會獲取 DOM 元素的絕對位置,例如 本文 左側(cè)的懸浮導航,當頁面滾動到它以前會正常地渲染到文檔流中,當頁面滾動超過了它的位置,就會始終懸浮在左側(cè)。
本文會詳述各種獲取 DOM 元素絕對位置 的方法以及對應的兼容性。關于如何獲取 DOM 元素高度和滾動高度,請參考視口的寬高與滾動高度 一文。
概述
這些是本文涉及的 API 對應的文檔和標準,供查閱:
| API | 用途 | 文檔 | 標準 |
|---|---|---|---|
| offsetTop | 相對定位容器的位置 | MDN | CSSOM View Module |
| clientTop | 上邊框?qū)挾?/td> | MDN | CSSOM View Module |
| .getBoundingClientRect() | 元素大小和相對視口的位置 | MDN | CSSOM View Module |
| .getClientRects() | 所有子 CSS 盒子的大小和位置 | MDN | CSSOM View Module |
| .getComputedStyle() | 應用所有樣式表和計算之后的 CSS 屬性 | MDN | DOM Level 2 Style CSSOM |
offsetTop/offsetLeft
HTMLElement.offsetTop 用來獲取當前元素(不包括上邊框)相對于定位容器(positioning container)的位置。也就是說,
如果所有祖先元素都是靜態(tài)定位 position:static;(這是默認的情況),offsetTop 表示與文檔最上方的高度差(文檔最上方可能已經(jīng)滾出視口,這個高度可能大于視口高度)。
如果存在絕對定位的祖先元素 position:absolute/fixed,offsetTop 就會相對于這個元素。因此為了獲取相對于文檔最上方的高度差,需要遞歸地調(diào)用:
function getOffsetTop(el){
return el.offsetParent
? el.offsetTop + getOffsetTop(el.offsetParent)
: el.offsetTop
}
el.offsetParent 是當前元素的定位容器(positioning container),如果當前元素沒有絕對定位的祖先節(jié)點,這個屬性的值就是 null。
兼容性和限制:幾乎所有瀏覽器都支持該屬性。如果元素被隱藏它的值就是 0,但在 IE9 下沒有影響。
clientTop/clientLeft
不要被名字誤導,Element.clientTop 是指當前元素的 上邊框的寬度 的整數(shù)值??偸堑扔?getComputedStyle() 返回的 border-top-width 屬性的四舍五入為整數(shù)后的值。
為什么呢?在 DOM 術語中,client 總是指除邊框(border)外的渲染盒子(內(nèi)邊距+內(nèi)容大?。ffset 總是指包含邊框的渲染盒子(邊框+內(nèi)邊距+內(nèi)容大?。?code class="highlighter-rouge">clientTop 即為這兩者的 Top 之差,即邊框?qū)挾取:凶拥母拍钫垍⒖迹篊SS Display 屬性與盒模型
兼容性和限制:同 offsetTop/offsetLeft
.getBoundingClientRect()
Element.getBoundingClientRect() 用于獲取元素的大小,以及相對于視口(viewport)的位置,返回一個 DOMRect 對象。
> document.querySelector('span').getBoundingClientRect()
DOMRect {x: 2.890625, y: 218.890625, width: 1264, height: 110, top: 218.890625, …}
bottom: 328.890625
height: 110
left: 2.890625
right: 1266.890625
top: 218.890625
width: 1264
x: 2.890625
y: 218.890625
如果要獲取相對于文檔左上角的位置,需要在上述 top 和 left 的基礎上再加滾動位置。如下代碼來自 MDN,可兼容幾乎所有瀏覽器:
// For scrollX (((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.scrollLeft == 'number' ? t : document.body).scrollLeft // For scrollY (((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.scrollTop == 'number' ? t : document.body).scrollTop
兼容性和限制:同樣是 CSSOM View Module 的特性,但幾乎兼容所有瀏覽器,可參考
https://caniuse.com/#feat=getboundingclientrectIE 下窗口的左上角可能不是 0,0,在 IE9 可以這樣把它設置為 0,0:
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
.getClientRects()
Element.getClientRects() 用來獲得 DOM 元素中的所有CSS 盒模型 對應的 DOMRect 組成的集合。
如果是一個塊級元素,返回的集合中應該只有一個元素,即這個塊的大小和位置。但如果是一個行內(nèi)元素(或者 SVG 內(nèi)的元素),則會返回其中每個 CSS 盒子。比如一個普通的被默認折行的 <span>:
> document.querySelector('span').getClientRects()
DOMRectList {0: DOMRect, 1: DOMRect, 2: DOMRect, length: 5}
0: DOMRect {x: 2.890625, y: 262.890625, width: 1264, height: 22, top: 262.890625, …}
1: DOMRect {x: 2.890625, y: 284.890625, width: 1264, height: 22, top: 284.890625, …}
2: DOMRect {x: 2.890625, y: 306.890625, width: 768, height: 22, top: 306.890625, …}
這個 <span> 有三行,其中第三行的長度不足一行,每次折行都形成了一個新的 CSS 盒子。
兼容性和限制:在 IE8 及以下會返回 IE 獨有的 TextRectangle 對象(而不是 ClientRect),這個對象不具有 width 和 height 屬性,而且無法給它設置屬性。參考:https://webplatform.github.io/docs/dom/HTMLElement/getClientRects/
.getComputedStyle()
Window.getComputedStyle() 可以得到一個元素的所有計算后的 CSS 屬性。對于簡單的絕對定位元素,可以通過這個 API 返回的 top,left 等屬性值獲取元素的位置。例如:
let btn = document.querySelector('#btn-scroll-up')
let {top, left} = getComputedStyle(btn)
console.log('top:', top, 'left:', left)
.getComputedStyle() 還有一個有用的用法,獲取偽元素的大小和位置等樣式信息:
// 以下代碼來自: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
var h3 = document.querySelector('h3');
var result = getComputedStyle(h3, ':after').content;
console.log('the generated content is: ', result); // returns ' rocks!'
兼容性和限制:.getComputedStyle() 幾乎兼容所有瀏覽器,可參考 https://caniuse.com/#search=getComputedStyle。但它返回的值是 CSS 屬性,用它獲取絕對位置時要注意值的類型。例如 left 可能是 13px 這樣的絕對值,也可能是 auto 這樣的 CSS 關鍵字。
總結(jié) 獲取 DOM 元素相對于文檔的位置,可以直接使用 offsetTop; 獲取 DOM 元素相對于視口的位置,可以使用 .getBoundingClientRect(); 獲取 SVG 元素或行內(nèi)元素的 CSS 盒子(比如用來做文本高亮時),可以使用 .getClientRects(); 獲取絕對定位元素、偽元素的渲染后 CSS 屬性,可以使用 .getComputedStyle()
總結(jié)
以上所述是小編給大家介紹的JS中獲取 DOM 元素的絕對位置實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
【JS+CSS3】實現(xiàn)帶預覽圖幻燈片效果的示例代碼
下面小編就為大家?guī)硪黄綣S+CSS3】實現(xiàn)帶預覽圖幻燈片效果的示例代碼。小編覺得挺不錯的,現(xiàn)在分享給大家。給大家一個參考2016-03-03
JavaScript中函數(shù)聲明優(yōu)先于變量聲明的實例分析
同一個標示符,先后用var和function聲明它。最后它是什么呢2012-03-03
利用js實現(xiàn)可進行時間和工作調(diào)度的任務管理器
這篇文章主要為大家詳細介紹了如何利用js實現(xiàn)一個可進行時間和工作調(diào)度的任務管理器,文中的示例代碼簡潔易懂,有需要的小伙伴可以參考一下2023-10-10
JS實現(xiàn)的數(shù)組去除重復數(shù)據(jù)算法小結(jié)
這篇文章主要介紹了JS實現(xiàn)的數(shù)組去除重復數(shù)據(jù)算法,總結(jié)分析了4種比較常見的數(shù)組去重復算法及相關使用技巧,需要的朋友可以參考下2017-11-11

