您好,登錄后才能下訂單哦!
在操作頁(yè)面滾動(dòng)和動(dòng)畫時(shí)經(jīng)常會(huì)獲取 DOM 元素的絕對(duì)位置,例如 本文 左側(cè)的懸浮導(dǎo)航,當(dāng)頁(yè)面滾動(dòng)到它以前會(huì)正常地渲染到文檔流中,當(dāng)頁(yè)面滾動(dòng)超過(guò)了它的位置,就會(huì)始終懸浮在左側(cè)。
本文會(huì)詳述各種獲取 DOM 元素絕對(duì)位置 的方法以及對(duì)應(yīng)的兼容性。關(guān)于如何獲取 DOM 元素高度和滾動(dòng)高度,請(qǐng)參考視口的寬高與滾動(dòng)高度 一文。
概述
這些是本文涉及的 API 對(duì)應(yīng)的文檔和標(biāo)準(zhǔn),供查閱:
API | 用途 | 文檔 | 標(biāo)準(zhǔn) |
---|---|---|---|
offsetTop | 相對(duì)定位容器的位置 | MDN | CSSOM View Module |
clientTop | 上邊框?qū)挾?/td> | MDN | CSSOM View Module |
.getBoundingClientRect() | 元素大小和相對(duì)視口的位置 | MDN | CSSOM View Module |
.getClientRects() | 所有子 CSS 盒子的大小和位置 | MDN | CSSOM View Module |
.getComputedStyle() | 應(yīng)用所有樣式表和計(jì)算之后的 CSS 屬性 | MDN | DOM Level 2 Style CSSOM |
offsetTop/offsetLeft
HTMLElement.offsetTop 用來(lái)獲取當(dāng)前元素(不包括上邊框)相對(duì)于定位容器(positioning container)的位置。也就是說(shuō),
如果所有祖先元素都是靜態(tài)定位 position:static;
(這是默認(rèn)的情況),offsetTop
表示與文檔最上方的高度差(文檔最上方可能已經(jīng)滾出視口,這個(gè)高度可能大于視口高度)。
如果存在絕對(duì)定位的祖先元素 position:absolute/fixed
,offsetTop
就會(huì)相對(duì)于這個(gè)元素。因此為了獲取相對(duì)于文檔最上方的高度差,需要遞歸地調(diào)用:
function getOffsetTop(el){ return el.offsetParent ? el.offsetTop + getOffsetTop(el.offsetParent) : el.offsetTop }
el.offsetParent
是當(dāng)前元素的定位容器(positioning container),如果當(dāng)前元素沒(méi)有絕對(duì)定位的祖先節(jié)點(diǎn),這個(gè)屬性的值就是 null
。
兼容性和限制:幾乎所有瀏覽器都支持該屬性。如果元素被隱藏它的值就是 0,但在 IE9 下沒(méi)有影響。
clientTop/clientLeft
不要被名字誤導(dǎo),Element.clientTop 是指當(dāng)前元素的 上邊框的寬度 的整數(shù)值??偸堑扔?getComputedStyle()
返回的 border-top-width
屬性的四舍五入為整數(shù)后的值。
為什么呢?在 DOM 術(shù)語(yǔ)中,client 總是指除邊框(border)外的渲染盒子(內(nèi)邊距+內(nèi)容大?。ffset 總是指包含邊框的渲染盒子(邊框+內(nèi)邊距+內(nèi)容大?。?,clientTop
即為這兩者的 Top 之差,即邊框?qū)挾取:凶拥母拍钫?qǐng)參考:CSS Display 屬性與盒模型
兼容性和限制:同 offsetTop/offsetLeft
.getBoundingClientRect()
Element.getBoundingClientRect() 用于獲取元素的大小,以及相對(duì)于視口(viewport)的位置,返回一個(gè) DOMRect 對(duì)象。
> 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
如果要獲取相對(duì)于文檔左上角的位置,需要在上述 top
和 left
的基礎(chǔ)上再加滾動(dòng)位置。如下代碼來(lái)自 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 可以這樣把它設(shè)置為 0,0:
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
.getClientRects()
Element.getClientRects() 用來(lái)獲得 DOM 元素中的所有CSS 盒模型 對(duì)應(yīng)的 DOMRect 組成的集合。
如果是一個(gè)塊級(jí)元素,返回的集合中應(yīng)該只有一個(gè)元素,即這個(gè)塊的大小和位置。但如果是一個(gè)行內(nèi)元素(或者 SVG 內(nèi)的元素),則會(huì)返回其中每個(gè) CSS 盒子。比如一個(gè)普通的被默認(rèn)折行的 <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, …}
這個(gè) <span>
有三行,其中第三行的長(zhǎng)度不足一行,每次折行都形成了一個(gè)新的 CSS 盒子。
兼容性和限制:在 IE8 及以下會(huì)返回 IE 獨(dú)有的 TextRectangle
對(duì)象(而不是 ClientRect
),這個(gè)對(duì)象不具有 width
和 height
屬性,而且無(wú)法給它設(shè)置屬性。參考:https://webplatform.github.io/docs/dom/HTMLElement/getClientRects/
.getComputedStyle()
Window.getComputedStyle() 可以得到一個(gè)元素的所有計(jì)算后的 CSS 屬性。對(duì)于簡(jiǎn)單的絕對(duì)定位元素,可以通過(guò)這個(gè) API 返回的 top
,left
等屬性值獲取元素的位置。例如:
let btn = document.querySelector('#btn-scroll-up') let {top, left} = getComputedStyle(btn) console.log('top:', top, 'left:', left)
.getComputedStyle()
還有一個(gè)有用的用法,獲取偽元素的大小和位置等樣式信息:
// 以下代碼來(lái)自: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle var h4 = document.querySelector('h4'); var result = getComputedStyle(h4, ':after').content; console.log('the generated content is: ', result); // returns ' rocks!'
兼容性和限制:.getComputedStyle()
幾乎兼容所有瀏覽器,可參考 https://caniuse.com/#search=getComputedStyle。但它返回的值是 CSS 屬性,用它獲取絕對(duì)位置時(shí)要注意值的類型。例如 left
可能是 13px
這樣的絕對(duì)值,也可能是 auto
這樣的 CSS 關(guān)鍵字。
總結(jié) 獲取 DOM 元素相對(duì)于文檔的位置,可以直接使用 offsetTop
; 獲取 DOM 元素相對(duì)于視口的位置,可以使用 .getBoundingClientRect()
; 獲取 SVG 元素或行內(nèi)元素的 CSS 盒子(比如用來(lái)做文本高亮?xí)r),可以使用 .getClientRects()
; 獲取絕對(duì)定位元素、偽元素的渲染后 CSS 屬性,可以使用 .getComputedStyle()
總結(jié)
以上所述是小編給大家介紹的JS中獲取 DOM 元素的絕對(duì)位置實(shí)例詳解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)億速云網(wǎng)站的支持!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。