原文地址:www.zhangxinxu.com/wordpress/?…html
題目以下(紙質打印拍攝圖):git
是至關簡單的一道題目,入門級別的,雖然挺簡單,但還有不少細節是不少人不知道的,所以仍是頗有價值的。github
本題主要考察窗體滾動,窗體高度獲取,普通元素高度獲取這幾個知識點。瀏覽器
本次B站直播在上午月10:15分開始,持續約40分鐘,有錄播,戳這裏瀏覽。安全
你們回答地址這裏:github.com/zhangxinxu/…bash
有很多人答題時候使用了節流函數,以下:微信
初衷是好的,滾動是一個高頻觸發的操做,經過節流函數能夠下降計算方法執行的頻率。可是,實際上,咱們開發的大多數頁面是如此的簡單,根本用不到須要節流函數,反而增長了代碼的複雜度,對於本題,能夠不須要。
dom
瀏覽器窗體滾動事件綁在哪一個對象上呢?是window
對象,仍是document
對象,或者是document.documentElement
,document.body
?ide
咱們不妨測試下:wordpress
window.addEventListener('scroll', function () {
console.log('window滾動觸發,window.pageYOffset是:' + this.pageYOffset);
});
document.addEventListener('scroll', function () {
console.log('document滾動觸發,document.scrollTop是:' + this.scrollTop);
});
document.documentElement.addEventListener('scroll', function () {
console.log('document.documentElement滾動觸發,document.documentElement.scrollTop是:' + this.scrollTop);
});
document.body.addEventListener('scroll', function () {
console.log('document.body滾動觸發,document.body.scrollTop是:' + this.scrollTop);
});複製代碼
您能夠識別此二維碼:
或者直接點擊這個頁面:scroll滾動容器測試demo
結果不管是PC,仍是移動端,測試結果以下:
也就是window
對象和document
對象綁定scroll事件能夠觸發,document.documentElement
和document.body
是不行的。
而後,直播的時候有人在羣裏反饋,本身的手機document
滾動沒法觸發,若是這是真的,那安全起見,默認的瀏覽器窗體滾動事件仍是綁定在window
對象上。
如何獲取窗體的滾動高度呢?常見的有下面3種代碼:
window.pageYOffset;
document.documentElement.scrollTop;
document.body.scrollTop;複製代碼
都是有效的嗎?
咱們不妨測試下,想辦法識別此二維碼:
或者直接訪問這個頁面:3種窗體滾動高度獲取方法測試demo
結果在PC上是這樣:
而在手機上則是:
能夠看到桌面瀏覽器和移動端瀏覽器對於滾動高度獲取是有差異的,桌面端瀏覽器不能使用document.body.scrollTop
獲取瀏覽器窗體的滾動高度,而移動端不能使用document.documentElement.scrollTop
獲取瀏覽器窗體的滾動高度。可是都支持window.pageYOffset
。
因此,理論上講,瀏覽器窗體的滾動高度獲取使用window.pageYOffset
便可,然而window.pageYOffset
有一個缺點,就是IE9及其以上瀏覽器才支持,在PC端,不少項目是須要兼容IE8瀏覽器的,所以,對於傳統PC網站,獲取瀏覽器窗體滾動高度比較好的表達方法是這樣:
var winScrollTop = window.pageYOffset || document.documentElement.scrollTop;複製代碼
這個可使用window.innerHeight
獲取。然而,window.innerHeight
有兼容性問題,IE8瀏覽器及其如下瀏覽器是不支持的,怎麼辦?能夠藉助document.documentElement.clientHeight
獲取。
因而:
pre>var winHeight = window.innerHeight || document.documentElement.clientHeight;
document.documentElement
是個很特殊的對象,他的不少行爲表現跟普通元素是不同的。例如,普通div這類元素的clientHeight
是不包括邊框大小的,可是,document.documentElement.clientHeight
直接無視這些,不管你<html>
元素是否設置了border
,都是頁面可視區域的高度。更神奇的是document.documentElement.offsetHeight
竟然是包含瀏覽器滾動高度的完整高度,等同於document.documentElement.scrollHeight
,你們能夠特殊記憶下。
普通元素的滾動直接添加scroll事件就行了,沒有任何兼容性差別。
dom.addEventListener('scroll', function () {
console.log('元素滾動觸發,滾動高度是:' + this.scrollTop);
});複製代碼
高度獲取則使用clientHeight
,由於滾動的內容是不包括border-box
的:
dom.addEventListener('scroll', function () {
if (this.scrollTop > this.clientHeight) {
console.log('滾動超過一屏了');
}
});複製代碼
對於普通元素的滾動高度獲取,還有不少其餘的原生API,例如offsetHeight
,包含border
邊框大小;scrollHeight
包括滾動高度;getBoundingClientRect().height也是高度獲取,不會能夠是小數,特殊場景挺有用的。
重要參考文檔
本文提到的pageYoffset,innerHeight,clientHeight,offsetHeight,getBoundingClientRect等原生API都屬於CSSOM視圖模式(CSSOM View Module)相關內容,本文這裏只是一部分,更多內容能夠參見本站經典文章:「CSSOM視圖模式(CSSOM View Module)相關整理」。
下次直播預告
下週三羣裏發佈CSS小測第2期正常,可是因爲週六上班,有恰逢春節,所以直播答疑推遲到年後。想加入個人粉絲羣的能夠加我微信好友 zhangxinxu-job,我拉大家進去,備註「入羣」,而後附上大家的姓名,方便我備註。
(完)