JS屬性scrollTop?clientHeight?scrollHeight理解學習
引言
在開發(fā)中我們常常會用到判斷滾動條是否觸底的邏輯。我一般都會在網(wǎng)上搜一段代碼,這段代碼有用到scrollTop、clientHeight、 scrollHeight 。接著我簡單看一下好像理解了,再在項目里用一下好使了就沒去深入研究相關概念。等下次用到了還是搜一下,自己寫不出來...于是筆者想想深入研究一下這些概念好擺脫尷尬的局面。
看了很多的文章,感覺有一些寫的不夠詳細具體,要么就是概念的堆砌沒有例子和圖,要么就是一張圖寫滿了各種概念不易于理解。于是筆者自己對照MDN文檔總結了一下這些概念,并結合示例加深對這些概念的理解,并總結了這些概念彼此之間的數(shù)量關系和應用場景。歡迎大家閱讀,有寫錯或者理解錯的地方請不吝指正。
1.clientWidth、clientHeight、clientLeft、clientTop
1.1 clientWidth
(1)含義:只讀屬性,表示元素的內部寬度,單位為像素。
(2)從盒子模型角度看:包含padding,但不包含border, margin 以及垂直滾動條。
(3)注意:內聯(lián)元素clientWidth為0。
(4)語法:element.clientWidth;

1.2 clientHeight
(1)含義:只讀屬性,表示元素的內部高度,單位為像素。
(2)從盒子模型角度看:包含padding,但不包含border, margin 以及水平滾動條。
(3)注意:內聯(lián)元素clientHeight為0。
(4)語法:element.clientHeight;
1.3 clientLeft
(1)含義:只讀屬性,表示一個元素左邊框的寬度,單位為像素。
(2)從盒子模型角度看:clientLeft 不包括左外邊距和左內邊距.
(3)語法:element.clientLeft
(4)備注:如果元素的文本方向是從右向左(RTL, right-to-left),并且由于內容溢出導致左邊出現(xiàn)了一個垂直滾動條,則該屬性包括滾動條的寬度。
1.4 clientTop
(1)含義:只讀屬性,表示一個元素頂部邊框的寬度,單位為像素。
(2)從盒子模型角度看:不包括頂部外邊距或內邊距
(3)語法:element.clientTop
1.5 示例演示
以如下的盒子模型來驗證來看一下這些值以及計算過程(采用的例子是MDN上的,您可以打開控制臺自己試一下):
(1)首先控制臺獲取Dom元素:
const div = document.getElementById('iddiv')
(2)然后在 Eelments->Computed 看盒模型:

(3)查看clientWidth的值:

clientWidth計算:內容寬度+左右padding即 182+28*2 = 182 + 56 = 238
(4)查看clientHeight的值:

clietentHeight計算:內容高度+上下padding即 102 + 0 = 102
(5)查看clientLeft和clientTop值:

clientLeft和clientTop計算:左邊框 24 ; 上邊框24
注意以上的計算過程是筆者在盒模型的設置為:box-sizing: content-box時的計算方法,如果盒模型設置為 box-sizing: border-box; 則計算clientWidth 和 clientHeight的方法為:
(1)clientWidth :clientWidth 可以通過 CSS width+ CSS padding - 垂直滾動條寬度 (如果存在) 來計算
(2)clientHeight:clientHeight 可以通過 CSS height + CSS padding - 水平滾動條高度 (如果存在) 來計算
以clientWidth的計算為例說明一下


首先按照正常算法計算: 95 + 28*2 = 95 + 56 = 151 。151大于134 , 時因為還沒有扣除滾動條的寬度,滾動條的寬度 為 151- 134 = 17 , 量了一下滾動條的寬度確實為17,如下圖所示:

2.offsetWidth、offsetHeight、offsetLeft、offsetTop
2.1 offsetWidth
(1)含義:只讀屬性,返回元素的布局寬度,單位像素。
(2)從盒子模型角度看:包含通過css設置的width,border, padding以及豎直方向滾動條的寬度。
(3)語法:element.offsetWidth
(4)備注:各瀏覽器的 offsetWidth 可能有所不同。
2.2 offsetHeight
(1)含義:只讀屬性,元素的布局高度,單位像素。
(2)從盒子模型角度看:包含通過css設置的height, border, padding以及水平方向滾動條的高度。
(3)語法:element.offsetHeight
(4)備注:如果元素被隱藏則返回0。
接下來要介紹offsetLeft和offsetTop的含義,在這之前要明白offsetParent的含義:
HTMLElement.offsetParent 是一個只讀屬性。
返回一個指向最近的(指包含層級上的最近)包含該元素的定位元素或者最近的 table,td,th,body元素。
當元素的 style.display 設置為 "none" 時,offsetParent 返回 null
2.3 offsetLeft
(1)含義:只讀屬性,當前元素左上角相對于offsetParent左邊界的偏移。
(3)語法:element.offsetLeft
(4)備注:如果元素被隱藏則返回0。
2.4 offsetTop
(1)含義:只讀屬性,當親元素相對于offsetParent元素的頂部內邊距的距離。
(3)語法:element.offsetTop
(4)備注:如果元素被隱藏則返回0。
2.5 示例演示
筆者寫了一個demo用來說明如上概念,代碼如下:
<html lang="en">
<head>
<style>
.parent {
width: 400px;
height: 400px;
border: 1px solid #ccc;
padding-top: 50px;
padding-left: 20px;
}
.child {
width: 200px;
height: 200px;
padding: 10px;
border: 10px solid black;
overflow: auto;
}
</style>
</head>
<body>
<div class="parent">
<div class="child" id="child-id">
<!-- 省略內部內容 -->
</div>
</div>
</body>
</html>
代碼運行效果以及盒子模型如下圖所示:


(1)獲取內部div Dom元素
const div = document.getElementById('child-id')
(2)查看offsetWidth的值

其計算過程:border 20 + pading 20 + content 183 + 滾動條 17 = 240。
也就是: 20 + 20 + 200= 240
如果設置 box-sizing:border-box 則對應的盒子模型變?yōu)椋?/p>

此時查看offsetWidth的值:

其計算過程: content 160 + padding 20 + border 20 = 200 。我們觀察實際效果:


發(fā)現(xiàn)雖然computed的盒子模型顯示padding是10 ,但實際上并不是10了,而且由于滾動條的存在左右顯示的padding所占空間已經(jīng)不相等。
(3)讀取offsetHeight值


計算過程與offsetWidth類似: 183 content + 17 滾動條 +20 padding + 20 border = 240。如果設置 box-sizing:border-box 則offsetHeight值如下:

(4)讀取offsetTop和offsetLeft的值

如上我們發(fā)現(xiàn)offsetParent為body元素, 那么offsetTop值為59 , offsetLeft的值為29,都是怎么算出來的啊?看一下body以及class為parent的外層div的盒模型結構:


參考盒子模型結構我們可以得到計算過程:
offsetTop : 8 (body padding) + 1 (parent border) +50 (parent padding) = 59
offsetLeft: 8 (body padding) + 1 (parent border) + 20 (parent padding) = 29
3.scrollLeft、scrollTop、scrollWidth、scrollHeight
3.1 scrollLeft
(1)含義:可讀取可設置,一個元素的內容水平滾動的像素數(shù)(滾動條到元素左邊的距離)。
(2)語法:Element.scrollLeft
(3)備注:注意如果這個元素的內容排列方向是rtl (right-to-left) ,那么滾動條會位于最右側(內容開始處),并且scrollLeft值為 0。此時,當你從右到左拖動滾動條時,scrollLeft 會從 0 變?yōu)樨摂?shù)。
3.2 scrollTop
(1)含義:可讀取可設置,一個元素的內容垂直滾動的像素數(shù)。
(2)語法:Element.scrollTop
(3)備注:一個元素的 scrollTop 值是這個元素的內容頂部(卷起來的)到它的視口可見內容(的頂部)的距離的度量。注意,這里并沒有描述為滾動條距離頂部的距離,當然這樣理解也沒問題。當一個元素的內容沒有產(chǎn)生垂直方向的滾動條,那么它的 scrollTop 值為0。
3.3 scrollWidth
(1)含義:只讀屬性,是一個元素內容寬度的度量,包括由于溢出導致的視圖不可見內容。
(2)語法:Element.scrollWidth
(3)備注:沒有水平滾動條的情況下,scrollWidth 值與元素視圖填充所有內容所需要的最小值clientWidth相同。
3.4 scrollHeight
(1)含義:只讀屬性,是一個元素內容高度的度量,包括由于溢出導致的視圖不可見內容。
(2)語法:element.scrollHeight
(3)備注:沒有垂直滾動條的情況下,scrollHeight 值與元素視圖填充所有內容所需要的最小值clientHeight相同。
為了說明scrollHeight 的含義,MDN文檔給出了如下的示意圖:

3.5 示例演示
示例代碼任然沿用2.5 節(jié)的demo示代碼, 運行效果如下:
(1)查看scrollLeft的值


如上圖所示:水平方向上滾動條沒有向右滾動時,則scrollLeft的值為0。


如上圖所示:水平方向滾動條向右滾動了一定距離,則此時scrollLeft的值為58。
(2)查看scrollTop的值


如上圖所示:豎直方向上滾動條沒有向下滾動時,則scrollTop的值為0。


如上圖所示:豎直方向上滾動條沒有向下滾動了一定距離,則此時scrollTop的值為59。
(3)查看crollWidth的值


如上圖所示:scrollWidth的值為704,代表內容的寬度。
(4)查看scrollHeight的值


如上圖所示:scrollHeight的值為262,代表內容的高度。
4.彼此之間的數(shù)量關系以及應用
(1)關系1
沒有豎直方向上的滾動條: scrollHeight = clientHeight
應用:判斷豎直方向是是否有滾動條
(2)關系2
沒有水平方向上的滾動條:scrollWidth = clientWidth
應用:判斷水平方向是否有滾動條
(3)關系3
scrollTop + clientHeight >= scrollHeight
因為scrollTop是一個非整數(shù),而scrollHeight和clientHeight是四舍五入的,因此確定滾動區(qū)域是否滾動到底的唯一方法是查看滾動量是否足夠接近某個閾值:
Math.abs(element.scrollHeight - element.clientHeight - element.scrollTop) < 1
5.總結
一圖勝千言,本文的全部內容如下:

以上就是JS屬性scrollTop clientHeight scrollHeight理解學習的詳細內容,更多關于JS屬性scrollTop clientHeight scrollHeight的資料請關注腳本之家其它相關文章!
相關文章
next.js源碼解析getStaticProps?getStaticPaths使用場景
這篇文章主要為大家介紹了next.js源碼解析getStaticProps?getStaticPaths使用場景,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
詳解微信小程序如何實現(xiàn)類似ChatGPT的流式傳輸
這篇文章主要為大家介紹了微信小程序如何實現(xiàn)類似ChatGPT的流式傳輸示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03

