Truth comes from practice
javascript
上來不說話,先拋出幾個問題:html
offsetWidth offsetHeight offsetLeft offsetTop
clientWidth clientHeight clientLeft clientTop
scrollWidth scrollHeight scrollLeft scrollTopjava
是時候談談它們之間的區別了,是否是已經混亂了?好吧,一步一步來搞清楚這些東西是啥。web
終於下決心來補上這個坑,俗話說的話:紙上得來終覺淺,絕知此事要躬行。要搞清這幾個容易混淆的概念,個人建議是運行文章中的例子。瀏覽器
任何HTML元素的只讀屬性offsetWidth和offsetHeight已CSS像素返回它的屏幕尺寸,返回的尺寸包乾元素的邊框和內邊距(width/height + border + padding),和滾動條。spa
全部HTML元素擁有offsetLeft和offsetTop屬性來返回元素的X和Y座標3d
相對於已定位元素的後代元素和一些其餘元素(表格單元),這些屬性返回的座標是相對於祖先元素code
通常元素,則是相對於文檔,返回的是文檔座標htm
offsetParent屬性指定這些屬性所相對的父元素,若是offsetParent爲null,則這些屬性都是文檔座標blog
//用offsetLeft和offsetTop來計算e的位置 function getElementPosition(e){ var x = 0,y = 0; while(e != null) { x += e.offsetLeft; y += e.offsetTop; e = e.offsetParent; } return { x : x, y : y }; }
client
是一種間接指代,它就是web瀏覽器客戶端,專指它定義的窗口或視口。
clientWidth和clientHeight相似於offsetWidth和offsetHeight,不一樣的是不包含邊框大小(width/height + padding)。同時在有滾動條的狀況下,clientWidth和clientHeight在其返回值中也不包含滾動條。
對於相似<i>、<code>、<span>等內聯元素,老是返回0
返回元素的內邊距的外邊緣和他的邊框的外邊緣的水平距離和垂直距離,一般這些值就等於左邊和上邊的邊框寬度。
在有滾動條時,而且瀏覽器將這些滾動條放置在左側或頂部(反正我是沒見過),clientLEft和clientTop就包含這些滾動條的寬度。
這兩個屬性是元素的內容區域加上內邊距,在加上任何溢出內容的尺寸.
所以,若是沒有溢出時,這些屬性與clientWidth和clientHeight是相等的。
指定的是元素的滾動條的位置
scrollLeft和scrollTop都是可寫的屬性,經過設置它們來讓元素中的內容滾動。
在這個實例中,咱們觀察#inner實例,看看該元素各個屬性之間的關係
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #wrap { border : 3px solid red; width: 600px; height : 600px; margin : 50px auto; } #inner { padding : 100px; width: 300px; height:200px; margin:50px auto; border:20px solid blue; overflow: auto; } #content{ width: 200px; height:800px; border:1px solid black; } </style> </head> <body> <div id="wrap"> <div id="inner"> <div id="content"></div> </div> </div> </body> </html>
var inner = document.getElementById('inner'); var content = document.getElementById('content'); //輔助變量,獲取元素的寬和高 var style = getComputedStyle(inner); //width & height console.log('width= '+style.width);// '' console.log('height= ' + style.height);// '' //padding console.log('paddingt-top='+style.paddingTop); console.log('paddingt-bottom= '+style.paddingBottom); console.log('paddingt-left= '+style.paddingLeft); console.log('paddingt-right= '+style.paddingRight); //border console.log('border-top-width= '+style.borderTopWidth); console.log('border-bottom-width= '+style.borderBottomWidth); console.log('border-left-width= '+style.borderLeftWidth); console.log('border-right-width= '+style.borderRightWidth); //offsetWidth & offsetWidth console.log('offsetWidth= '+inner.offsetWidth); console.log('offsetHeight= '+inner.offsetHeight); //clientWidth & clientHeight console.log('clientWidth= '+inner.clientWidth); console.log('clientHeight= '+inner.clientHeight); // scrollWidth & scrollHeight console.log('scrollWidth= '+inner.scrollWidth); console.log('scrollHeight= '+inner.scrollHeight); // #content.offsetHeight console.log('#content.offsetHeight= '+content.offsetHeight);
因爲元素是外鏈的樣式,沒有設置style,所以若是直接使用inner.style.width
返回的是空。必須使用getComputedStyle(el)
來獲取元素的寬和高
說明:
寬度
width:原本應該是300,可是因爲存在滾動條(在水平方向佔據了空間),所以
`本來內容區寬度(width) - 滾動條寬度 = 300 - 17 = 283`
offsetWidth:元素實際所佔空間,滾動條也是元素佔據的空間,所以
`width + 滾動條 + padding + border = 300 + 100 + 100 + 20 + 20 = 540`
clientWidth:除去邊框佔據的空間,且不包含滾動條
`width + padding = 283 + 100 + 100 = 483`
scrollWidth:因爲水平方向沒有溢出,所以
`clientWidth + 溢出部分 = 483 + 0 = 483`
高度
height:因爲垂直方向沒有滾動條佔據空間,所以
`本來內容區高度(height)- 滾動條高度 = 200 - 0 = 200`
offsetHeight:元素實際所佔空間,因爲採起了滾動的方式處理了溢出的部分,所以
`height + padding + border = 200 + 100 + 100 + 20 + 20 = 440`
clientHeight:
`height + padding = 200 + 100 + 100 = 400`
scollHeight:客戶區高度,加上溢出的部分,即包含元素真實高度-內容區的高度
`height+padding+(#content.offsetHeight-height)=200+100+100+802-200=1002`
html結構與上一個實例一直。這樣能夠
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #wrap { border : 3px solid red; width: 600px; height : 600px; margin : 50px auto; position:relative; } #inner { padding : 100px; width: 300px; height:200px; margin:50px auto; border:20px solid blue; overflow: auto; } #content{ width: 200px; height:800px; border:1px solid black; } </style> </head> <body> <div id="wrap"> <div id="inner"> <div id="content"></div> </div> </div> </body> </html>
分別獲取屬性
var inner = document.getElementById('inner'); //offsetLeft & offsetTop console.log("offsetLeft= "+inner.offsetLeft); console.log("offsetTop= "+inner.offsetTop); //clientLeft & clientTop console.log("clientLeft= "+inner.clientLeft); console.log("clientTop= "+inner.clientTop); // scrollLeft & scrollTop console.log("scrollLeft= "+inner.scrollLeft); console.log("scrollTop= "+inner.scrollTop); //讓文檔滾動 inner.scrollTop = 30; //爲了計算的方便 var style = getComputedStyle(inner);
結果如圖
分析:
(#wrap爲參照原點,設置了position:relative
)
offsetLeft:即元素的x座標,(#inner設置了自動居中)
`offsetLeft = (#wrap.width - #inner.offsetWidth)/2 =30`
offsetTop:即元素的y座標,(style是#inner元素的計算後的樣式)
`offsetTop = style.marginTop = 50`
clientLeft 即 border-left-width
`clientLeft = style.borderLeftWidth = 20`
clientTop 即 border-top-width
`clientTop = style.borderTopWidth = 20`
scrollLeft 因爲水平方向沒有滾動條,所以爲0
scrollTop 即滾動條離#inner border-top內側的位置,一開始爲0
大部分人看完的當時是知道的,過些日子可能又忘。我以爲是這幾個概念的名字取得很差,不太容易讓人望文生義。說了那麼多,不點個收藏以往往後回憶嗎?(世上竟有如此厚顏無恥之人,哈哈^_^#)