获取html元素的位置,如何获取页面元素的位置
背景:最近在商品列表項目迭代中,需要在商品列表底部增加一個分銷商品廣告位,另外接收到一個產品曝光度的埋點需求,需要知道產品出現在用戶視口后在進行數據統計!
基于虛擬 DOM 數據驅動的思想,最不提倡的就是 jquery 時代的 DOM 操作!但是在目前一些復雜的頁面中經常還是會用 javascript 處理一些 DOM 元素,實現一些動態效果;最常見的是用到一些元素的位置和尺寸的計算,但是其中瀏覽器的兼容性問題也是不可忽略的一部分,要想寫出預想效果的JavaScript代碼,我們需要了解一些基本知識。
基本概念
網頁大小:一張網頁的全部面積,就是它的大小。通常情況下,網頁的大小由內容和 CSS 樣式表決定。
瀏覽窗口大小:指的是在瀏覽器窗口中看到的那部分網頁面積,又叫做 viewport (視口)。
如果網頁的內容能夠在瀏覽器中全部顯示(也就不出現滾動條),那么網頁的大小和瀏覽器窗口的大小是相等的。如果不能全部顯示,則滾動瀏覽器窗口,可以顯示出網頁的各個部分。
基本元素屬性
在每個HTML元素都有下列屬性。
offsetWidth
clientWidth
scrollWidth
offsetHeight
clientHeight
scrollHeight
offsetLeft
clientLeft
scrollLeft
offsetTop
clientTop
scrollTop
為了理解方便這些屬性,我們需要知道 HTML 元素的實際內容有可能比分配用來容納內容的盒子更大,因此可能會出現滾動條,內容區域是視口,當實際內容比視口大的時候,需要把元素的滾動條位置考慮進去。
clientHeight 和 clientWidth 用于描述元素內尺寸,是指元素內容+內邊距大小,不包括邊框(IE下實際包括)、外邊距、滾動條部分
offsetHeight 和 offsetWidth 用于描述元素外尺寸,是指元素內容+內邊距+邊框,不包括外邊距和滾動條部分
clinetTop 和 clinetLeft 返回內邊距的邊緣和邊框的外邊緣之間的水平和垂直距離,也就是左,上邊框寬度
offsetTop 和 offsetLeft 表示該元素的左上角(邊緣外邊框)與已定位的父容器(offsetParent對象)左上角的距離
offsetParent 對象是指元素最近的定位(relative、absolute)祖先元素,遞歸上溯,如果沒有祖先元素是定位的話,會返回 null
獲取視口大小
網頁上的每個元素,都有 clientHeight 和 clientWidth屬性。這兩個屬性指元素的內容部分再加上 padding 的所占據的視覺面積,不包括 border 和滾動條占用空間。
因此,document 元素的 clientHeight 和 clientWidth 屬性,就代表了網頁的大小
function getViewport(){
if(!document) {
return {}
}
if (document.compatMode === 'BackCompat') {
return {
width: document.body.clientWidth,
height: document.body.clientHeight
};
}
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
};
}
復制代碼
上面的 getViewport 函數就是可以返回瀏覽器窗口的高和寬。使用的時候,有三個地方需要注意:
該函數必須在頁面加載完成后才能運行,否則 document 對象還沒有生成,瀏覽器會報錯。
大多數情況下,都是 document.documentElement.clientWidth 返回正確值。但是,在 IE6 的 quirks 模式中, document.body.clientWidth 返回正確的值,因此函數中加入了對文檔模式的判斷
clientWidth 和 clientHeight 都是只讀屬性,不能對它們賦值。
獲取視口大小的另一種方式
網頁中的每一個元素還有 srcollHeight 和 scrollWidth 屬性,指包含滾動在內的該元素的視覺面積。
那么,document 對象的 scrollHeight 和 scrollWidth 屬性就是網頁的大小,意思就是滾動條滾過的所有長度和寬度。
仿照 getViewport 函數,可以寫出 getPagearea() 函數。
function getPagearea(){
?if (document.compatMode == 'BackCompat') {
??return {
??? width: Math.max(document.body.scrollWidth, document.body.clientWidth),
??? height: Math.max(document.body.scrollHeight, document.body.clientHeight)
};
?}
?return {
width: Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth),
?height: Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight)
??};
}
復制代碼
相對文檔與視口的坐標
當我們在計算一個 DOM 元素位置也就是坐標的時候,會涉及到兩種坐標系, 文檔坐標__和__視口坐標。
我們經常用到的document就是整個頁面部分,而不僅僅是窗口可見部分,還包括因為窗口大小限制而出現滾動條的部分,它的左上角就是我們所謂相對于文檔坐標的原點。
視口是顯示文檔內容的瀏覽器的一部分,它不包括瀏覽器外殼(菜單,工具欄,狀態欄等),也就是當前窗口顯示頁面部分,不包括滾動條。
如果文檔比視口小,說明沒有出現滾動,文檔左上角和視口左上角相同,一般來講在兩種坐標系之間進行切換,需要加上或減去滾動的偏移量(scroll offset)。
為了在坐標系之間進行轉換,我們需要判定瀏覽器窗口的滾動條位置。window對象的pageXoffset和pageYoffset提供這些值,IE 8及更早版本除外。也可以通過scrollLeft和scrollTop屬性獲得滾動條位置,正常情況下通過查詢文檔根節點(document.documentElement)來獲得這些屬性值,但在怪異模式下必須通過文檔的body上查詢。
文檔坐標
任何HTML元素都擁有offectLeft和offectTop屬性返回元素的X和Y坐標,對于很多元素,這些值是文檔坐標,但是對于以定位元素后代及一些其他元素(表格單元),返回相對于祖先的坐標。我們可以通過簡單的遞歸上溯累加計算
function getElementPosition(e){
let x = 0;
let y = 0;
while (e != null) {
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
}
return { x, y };
}
復制代碼
盡管如此,這個函數也不總是計算正確的值,當文檔中含有滾動條的時候這個方法就不能正常工作了,我們只能在沒有滾動條的情況下使用這個方法,不過我們用這個原理算出一些元素相對于某個父元素的坐標。
快速方法:
網頁元素的相對位置就是:
let X = element.getBoundingClientRect().left;
let Y = element.getBoundingClientRect().top;
復制代碼
視口坐標
計算視口坐標就相對簡單了很多,可以通過調用元素的getBoundingClientRect方法。方法返回一個有left、right、top、bottom屬性的對象,分別表示元素四個位置的相對于視口的坐標。getBoundingClientRect所返回的坐標包含元素的內邊距和邊框,不包含外邊距。兼容性很好,非常好用
function getElementViewTop(element){
let actualTop = element.offsetTop;
let current = element.offsetParent;
let elementScrollTop;
while (current !== null) {
actualTop += current.offsetTop;
current = current.offsetParent;
}
if (document.compatMode == 'BackCompat') {
elementScrollTop = document.body.scrollTop;
} else {
elementScrollTop = document.documentElement.scrollTop;
}
return actualTop - elementScrollTop;
}
function getElementViewLeft(element){
let actualLeft = element.offsetLeft;
let current = element.offsetParent;
let elementScrollLeft;
while (current !== null) {
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
if (document.compatMode == 'BackCompat') {
elementScrollLeft = document.body.scrollLeft;
} else {
elementScrollLeft = document.documentElement.scrollLeft;
}
return actualLeft - elementScrollLeft;
}
復制代碼
快速方法:
使用 getboundingClientRect() 方法。它返回一個對象,其中包含了 left 、 top 、 width 、 height 等屬性。
let X = element.getBoundingClientRect().left;
let Y = element.getBoundingClientRect().top;
復制代碼
再加上滾動 距離,就可以得到絕對位置:
const X= element.getBoundingClientRect().left+document.documentElement.scrollLeft;
const Y =element.getBoundingClientRect().top+document.documentElement.scrollTop;
復制代碼
總結
以上是生活随笔為你收集整理的获取html元素的位置,如何获取页面元素的位置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html5支付宝主页面代码,JavaSc
- 下一篇: html5场景编辑工具,3款容易上手的H