轉載自:https://www.imooc.com/article/17571
網頁可見區域高:document.body.clientHeight
網頁正文全文高:document.body.scrollHeight
網頁可見區域高(包括邊線的高):document.body.offsetHeight
網頁被卷去的高:document.body.scrollTop
屏幕分辨率高:window.screen.height
每個HTML元素都具有clientHeight offsetHeight scrollHeight offsetTop scrollTop 這5個和元素高度、滾動、位置相關的屬性,單憑單詞很難搞清楚分別代表什么意思之間有什么區別。通過閱讀它們的文檔總結出規律如下:
clientHeight和offsetHeight屬性和元素的滾動、位置沒有關系它代表元素的高度,其中:
clientHeight:包括padding但不包括border、水平滾動條、margin的元素的高度。對于inline的元素這個屬性一直是0,單位px,只讀元素。
offsetHeight:包括padding、border、水平滾動條,但不包括margin的元素的高度。對于inline的元素這個屬性一直是0,單位px,只讀元素。
接下來討論出現有滾動條時的情況:
當本元素的子元素比本元素高且overflow=scroll時,本元素會scroll,這時:
scrollHeight: 因為子元素比父元素高,父元素不想被子元素撐的一樣高就顯示出了滾動條,在滾動的過程中本元素有部分被隱藏了,scrollHeight代表包括當前不可見部分的元素的高度。而可見部分的高度其實就是clientHeight,也就是scrollHeight>=clientHeight恒成立。在有滾動條時討論scrollHeight才有意義,在沒有滾動條時scrollHeight==clientHeight恒成立。單位px,只讀元素。
scrollTop: 代表在有滾動條時,滾動條向下滾動的距離也就是元素頂部被遮住部分的高度。在沒有滾動條時scrollTop==0恒成立。單位px,可讀可設置。
offsetTop: 當前元素頂部距離最近父元素頂部的距離,和有沒有滾動條沒有關系。單位px,只讀元素。
offsetTop: 當前元素頂部距離最近父元素頂部的距離,和有沒有滾動條沒有關系。單位px,只讀元素。
以下內容轉載自:
https://blog.csdn.net/shibazijiang/article/details/103894498
我們開發web代碼的時候,經常會遇到各種高度的計算. 因為總是忘記幾者之間得區別,每次都要現查,這次通過這篇文章徹底搞明白這幾個長度的區別.
1.定義說明
條目 | 含義 | 圖示 |
---|---|---|
clientHeight | 元素的像素高度,包含元素的高度+內邊距,不包含水平滾動條,邊框和外邊距 | 在這里插入圖片描述
|
offsetHeight | 元素的像素高度 包含元素的垂直內邊距和邊框,水平滾動條的高度,且是一個整數 | 在這里插入圖片描述
|
scrollHeight | 元素內容的高度,包括溢出的不可見內容 | 在這里插入圖片描述
|
offsetLeft | 返回元素左上角相對于offsetParent的左邊界的偏移像素值 |
注意點
1.對塊級元素來說,offsetTop、offsetLeft、offsetWidth 及 offsetHeight 描述了元素相對于 offsetParent 的邊界框。但是文本框不是如此.文本框的offsetLeft和offsetTop是第一個文本框的左偏移和上偏移.
2.offsetParent元素指改元素的定位元素以及最近的table,td,th,body.
可見,offsetParent和position屬性的包含塊概念類似.大部分場景下可以通用.
3.offsetTop和offsetLeft都是相對于其內邊距邊界的.
offsetLeft和left屬性的區別
1.position為fixed時值不同
當position為fixed的時候,offsetLeft的值將會是null,而left此時一般有確定的數字值.
2.相對邊距不同
offerset的是相對于offsetParent的內邊距邊界,left是相對于包含塊的外邊距邊界.
3.包含塊有區別
offerset相對與定位的祖先元素或者 table/td/th/body等祖先元素,left僅僅是相對于定位祖先元素+body
clientHeight與offsetHeight的區別
clientHeight僅僅包含內邊距+高度,offsetHeight包含內邊距+滾動條+邊框
所以可以這樣說: clientHeight+滾動條高度+邊框 = offsetHeight
參考資料:
1.offsetHeight官方說明
https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/offsetHeight
2.clientHeight官方說明
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/clientHeight
二、js事件對象Event獲取pageX,clientX,screenX,offsetX,layerX的方式與區別
pageX:
鼠標在頁面上的位置,從頁面左上角開始,即是以頁面為參考點,同一個元素坐標不隨滑動條移動而變化
clientX:
鼠標在頁面上可視區域的位置,即是以瀏覽器滑動條此刻的滑動到的位置為參考點,同一個元素坐標隨滑動條移動而變化.
注:
1、如果元素位于body中,e.clientX + document.body.scrollLeft - document.body.clientLeft = e.pageX,
2、e.clientX包括了body的邊框,document.body.scrollLeft也包括了body邊框,body表框運算重復,減去document.body.clientLeft,即去掉重復的body邊框
screenX:
獲取到的是觸發點相對顯示器屏幕左上角的距離,不隨頁面滾動或瀏覽器移動而改變
offsetX:
獲取到的是鼠標觸發點相對于目標事件元素(被觸發DOM)左上角的距離(確切的說是到邊框外邊界的距離),其中在IE中以內容區左上角為基準點不包括邊框,如果觸發點在邊框上會返回負值,而chrome中以邊框左上角為基準點。
layerX:
獲取到的是鼠標觸發點相對于offsetParent元素左上角的距離(確切的說是到邊框外邊界的距離),包括中間所有元素的padding、margin、border及元素寬度值之和),其中在IE中以內容區左上角為基準點不包括邊框,如果觸發點在邊框上會返回負值,而chrome中以邊框左上角為基準點。
注:關于offsetParent元素
1、如果當前元素的祖先元素沒有進行CSS定位(position為absolute或relative),offsetParent為body。
2、如果當前元素的祖先元素(包括當前元素)中有CSS定位(position為absolute或relative),offsetParent取最近的那個祖先元素(包括當前元素)。
總結:
1、使用pageX獲取帶滾動條的到頁面邊緣尺寸
2、使用clientX獲取到瀏覽器可是區域的尺寸,沒有滾動條,pageX == clientX
3、使用screenX獲取到屏幕邊緣尺寸
4、使用offsetX獲取到當前元素邊緣尺寸
5、使用layerX獲取到offsetParent邊緣尺寸
三、頁面元素坐標和偏移(clientX/pageX/screenX/layerX/offsetWidth/scrollWidth/clientWidth等)相關整理
鼠標事件都是在特定位置發生的,我們可以通過event事件對象的各種屬性來獲得事件發生的坐標位置,有相對于視口的,有相對于整個文檔的,同樣頁面元素的位置也有相對視口的,也有滾動后的,這些都比較容易混淆,所以整理在這里,備忘,待查。
1.客戶區坐標位置(clientX/clientY)
我們可以通過event事件對象的clientX/clientY屬性獲得事件發生時鼠標指針在視口中的水平和垂直坐標。
示意圖:
2.屏幕坐標位置(screenX/scrennY)
通過event事件對象的screenX/screenY屬性,可以獲取鼠標事件發生時鼠標光標相對于整個電腦屏幕的坐標信息。
示意圖:
clientX/clientY和screenX/screenY區別demo:clientX/clientY和screenX/screenY區別demo
demo 源代碼戳這里:https://github.com/demo.html
3.頁面坐標位置(pageX/pageY)
通過事件對象的pageX/pageY屬性可以獲得鼠標事件發生時鼠標光標相對于整個文檔元素的坐標位置(包含滾動)。
在頁面沒有滾動的情況下,通常pageX/pageY的值與clientX/clientY的值相等。
4.layerX/layerY
事件對象還有個不那么常見的屬性,那就是layerX/layerY,他是對于絕對定位元素來說的,相對于當前點擊元素的左上角定位的。當頁面上的元素時相對定位(position:relative)的時候,通常pageX/pageY和layerX/layerY的值是相同的,但是當元素絕對定位(position:absolute)了的時候,layerX/layerY就將鼠標光標位置相對于本身的左上角定位了。
下面demo有助于理解,猛戳:
pageX\pageY & layerX\layerY示意demo:pageX\pageY & layerX\layerY
demo代碼猛戳這里:https://github.com/pageXandLayerX.html
5.偏移量:(offsetWidth/offsetHeight/offsetLeft/offsetTop)
元素的偏移量(offsetLeft/offsetTop)是相對于它的直接父元素來說的。
[元素的可見大小由其高度和寬度決定,這包括所有的內邊距(padding)、滾動條和邊框(border)大小(注意這里面不包括margin喔,因為margin是透明的,一般使用它控制元素之間的間隔)。這是為什么呢,因為吧,可以一試,如果我們給元素添加背景的話,那么背景會被應用 于由內容和內邊距組成的區域,而添加邊框(border)會在內邊距(padding)的區域外邊加一條線,margin透明,當然不在可見范圍內啦。]
示意圖:
Tips:
1.如果要想知道某個元素在頁面上的偏移量,將這個元素的offsetLeft和offsetTop與其offsetParent的相同屬性相加,如此循環至根元素,就可以得到一個基本準確的值。
2.如果有些div他的offsetParent是<body>的話,那么也可以嘗試getElementLeft()和getElementTop()方法,不出意外地話會返回跟offsetLeft和offsetTop相同的值。
3.所有這些偏移量都是只讀的,而且每次訪問的時候都需要重新計算,要注意性能問題。
6.客戶區的大小(clientWidth/clientHeight)
元素的客戶區的大小就是指元素內容及其內邊距所占空間的大小(滾動條占用的空間不計算在內)。(clientWidth=width+padding(left、right);clientHeight=height+padding(top、bottom))
clientWidth與offsetWidth區別示例:[clientWidth與offsetWidth區別](http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/clientWidth.htm)
7.滾動大小(scrollWidth/scrollHeight/scrollLeft/scrollTop)
有些元素,即使沒有執行任何代碼也會自動的添加滾動條,如<html>,但是另外一些元素,則需要通過css的overflow屬性進行設置才能滾動。
通常認為<html>元素是在web瀏覽器的視口中滾動的元素(ie6之前版本運行在混雜模式下是<body>元素,這也是上面計算視口大小代碼if,else的原因),因此帶有垂直滾動條的頁面總高度就是document.documentElement.scrollHeight。

當overflow屬性設置為 auto時,內容可以超過元素的尺寸,并顯示滾動條。這時就可以使用scrollwidth屬性來檢索內容的寬度范圍內的元素。
MSDN上找到了相關的例子:scrollWidth屬性示例
更具體的信息,可以查看這里:MSDN scrollWidth
Tips:
在確定文檔的總高度時,必須取得scrollWidth、clientWidth和scrollHeight、clientHeight中的最大值,這樣才能保證在跨瀏覽器的情況下取得較為準確的結果。
8.window.scrollX/window.scrollY與window.pageXOffset/window.pageYOffset
window.scrollX/window.scrollY返回的是整個文檔document在水平和豎直方向滾動了的距離。
window.pageXOffset/window.pageYOffset相當于window.scrollX/window.scrollY的別名一樣的。也就是說:
window.pageXOffset == window.scrollX; // 總是返回真
但在跨瀏覽器的情況下,盡量使用window.pageXOffset/window.pageYOffset比較好。
所以為了保險起見,使用下面這樣的代碼來判斷文檔在垂直和水平防線滾動的距離比較好:
var x = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft; var y = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
9.window.innerHeight/window.innerWidth
window.innerHeight/window.innerWidth記錄了視口內文檔元素的實際高度和寬度,實際上還有window.outerHeight/window.outerWidth。
下圖可以很好地區分兩者:
另外,如果頁面滾動了也不會影響他的innerHeight和innerWidth值:
此外,如果頁面中有frameset時:
var intFrameHeight = window.innerHeight; // or
var intFrameHeight = self.innerHeight;
// will return the height of the frame viewport within the frameset
var intFramesetHeight = parent.innerHeight;
// will return the height of the viewport of the closest frameset
var intOuterFramesetHeight = top.innerHeight;
// will return the height of the viewport of the outermost frameset
10.getBoundingClientRect()方法
getBoundingClientRect用于獲得頁面中某個元素的左,上,右和下分別相對瀏覽器視窗的位置。getBoundingClientRect是DOM元素到瀏覽器可視范圍的距離(不包含文檔卷起的部分)。該函數返回一個Object對象,該對象有6個屬性:top,lef,right,bottom,width,height;這里的top、left和css中的理解很相似,width、height是元素自身的寬高,但是right,bottom和css中的理解有點不一樣。right是指元素右邊界距窗口最左邊的距離,bottom是指元素下邊界距窗口最上面的距離。
通過這個方法可以比較方便的獲取頁面元素的位置:
var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;
var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;
關于這個方法MSDN上有詳細的解釋:getBoundingClientRect()方法
總結:
上面那些屬性都是很容易搞混的。而且也要注意不同的瀏覽器中可能存在的差別,使用的時候測試一下就能更準確的應用了。
搞清楚了上面這些相關屬性和方法,應該就能理解小胡子寫給我的這個demo了: js原生拖放
源代碼在這里:https://github.com/dragdemo.html
整理這篇文章的契機,就是我在實現原生的拖放功能。
備忘,待查。