今天先來認識元素的尺寸怎麽抓座標,對今天只是想找元素的尺寸與座標而已。
如果有寫過Javascript30的朋友,應該知道裡面有幾天都在抓座標取特定的尺寸,而我感覺就是跟著看、跟著讀、跟著用,但實際上看了文件後還是一片混亂,所以先把範圍鎖小在今天的元素。
offset
的特徵是計算偏離祖先元素的位置。
會被決定為祖先元素的優先順序如下:
position
:absolute
、relative
、fixed
、sticky
<table>
、<td>
、<th>
<body>
示範祖父元素中有定位:
<div class='outer'>
<div class='inner'>
<p>inner</p>
<div>
</div>
.outer{
display:flex;
align-content:center;
position:absolute;
width:200px;
height:200px;
padding:10px;
background-color:gray;
}
.inner{
width:50px;
height:50px;
padding:10px;
margin:auto;
border:5px solid;
background-color:orange;
}
const inner = document.querySelector('.inner')
console.log(inner.offsetParent)//div.outer
示範使用到<table>
HTML結構:
<table>
<tr>
<td>
<div class='outer'>
<div class='inner'><p>inner</p></div>
</div>
</td>
</tr>
</table>
const inner = document.querySelector('.inner')
console.log(inner.offsetParent)//td
在某些狀態下,元素如果符合條件,那offsetParent
會是null
。
<body>
或<HTML>
。position
為fixed
。display:none
或者根本不在document
上面。找到祖父元素後,就可以使用這組方法找到相對於祖父元素偏離的距離,比方說呈現在畫面上有兩個方塊。
<div class='outer'>outer
<div class='inner'>
<p>inner</p>
</div>
</div>
const inner = document.querySelector('.inner')
console.log(`X為${inner.offsetLeft},Y為${inner.offsetTop}`)
//X為43,Y為10
offset計算的是元素的content
+padding
+scroll
+border
。
注意,不是設定的width
,是元素本身的內容大小content
。
現在我把上面的橘色區塊加上很多文字,改變CSS樣式,讓他能夠被捲軸捲動。
<div class='outer'>outer
<div class='inner'>
<p>
innerinnerinnerinnerinnerinnerinnerinner
innerinnerinnerinnerinnerinnerinnerinnerinnerinnerinner
innerinnerinnerinnerinnerinnerinnerinnerinnerinnerinner
</p>
<div>
</div>
現在的模樣長的像下面:
(這是圖片)
.outer{
display:flex;
align-content:center;
width:200px;
height:200px;
padding:10px;
background-color:gray;
}
.inner{
width:50px;
height:50px;
padding:10px;
border:5px solid;
background-color:orange;
overflow: auto;
word-break:break-all;
}
const inner = document.querySelector('.inner')
console.log(`寬為${inner.offsetWidth},高為${inner.offsetHeight}`)//寬為80,高為80
剛剛有提到寬高是content
+padding
+scroll
+border
,在box model
顯示inner
的content
是38,所以38+10 * 2+5 * 2加上捲軸寬就是這個元素的offsetWidth
了。至於高度不受捲軸影響,所以是50+10 * 2+5 * 2。
client比較像計算元素本身一些細節。
clientTop
跟Left
這段距離是元素的border
加上捲軸(如果是從文字由右到左,並且文字溢出導致多出捲軸)的寬度。
.inner{
width:50px;
height:50px;
padding:10px;
border:5px solid;
background-color:orange;
overflow: auto;
word-break:break-all;
}
const inner = document.querySelector('.inner')
console.log(`X為${inner.clientLeft},Y為${inner.clientTop}`)
//X為5,Y為5
clientWidth
跟clientHeight
的寬高是元素的content加上padding。
const inner = document.querySelector('.inner')
console.log(`寬為${inner.clientWidth},高為${inner.clientHeight}`)
//寬為58,高為58
其中padding
為10,元素本身內容的寬度為38,所以加起來就是58。
scroll是把超出的文字改成捲動之後,尺寸是可見內容加上被隱藏的部份。
比方說以這張圖來說,第二行下面還有很多的空間裝著文字,這些就是scroll
的範圍。
left跟top都是滾動的距離。
const inner = document.querySelector('.inner')
//以事件測試輸出捲動距離
inner.addEventListener('scroll',()=>{
console.log(inner.scrollTop)
})
scrollWidth
跟scrollHeight
計算隱藏的空間大小。
const inner = document.querySelector('.inner')
console.log(inner.scrollWidth)//240
Element.getBoundingClientRect()
會回傳一個DOMRect
物件,這個物件會顯示相對viewport左上角的一些距離,分別有一些屬性可以使用。
bottom
是從視口到元素底部的距離,而right
則是視口到元素右邊邊框的距離,所以右邊跟下面如果有padding
跟border
這些看得到的空間就會加上去,但margin就沒有。
width跟height是元素本身加上padding
跟border
的距離,但如果有先設定box-sizing
為border-box
,那麽寬高就等同於width
跟height
。
top跟y、left跟x基本上這一組數值會一樣。
這些數值會依照視口的捲動改變。
如上圖往下拉之後,y
會因為空間變少的關係變少或者是負的,而bottom
也是一樣。
Element size and scrolling
Element: getBoundingClientRect() method