粉絲羣DOM小測第27期直播答疑文字版

原文地址:www.zhangxinxu.com/wordpress/?…html

1、題目與考察點

題目以下(紙質打印拍攝圖):git

DOM小測題目

是至關簡單的一道題目,入門級別的,雖然挺簡單,但還有不少細節是不少人不知道的,所以仍是頗有價值的。github

本題主要考察窗體滾動,窗體高度獲取,普通元素高度獲取這幾個知識點。瀏覽器

本次B站直播在上午月10:15分開始,持續約40分鐘,有錄播,戳這裏瀏覽。安全

2、答疑內容

你們回答地址這裏:github.com/zhangxinxu/…bash

1. 關於節流函數

有很多人答題時候使用了節流函數,以下:微信

節流函數代碼截圖

初衷是好的,滾動是一個高頻觸發的操做,經過節流函數能夠下降計算方法執行的頻率。可是,實際上,咱們開發的大多數頁面是如此的簡單,根本用不到須要節流函數,反而增長了代碼的複雜度,對於本題,能夠不須要。
dom

2. 窗體滾動事件綁在哪裏?

瀏覽器窗體滾動事件綁在哪一個對象上呢?是window對象,仍是document對象,或者是document.documentElementdocument.bodyide

咱們不妨測試下: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.documentElementdocument.body是不行的。

而後,直播的時候有人在羣裏反饋,本身的手機document滾動沒法觸發,若是這是真的,那安全起見,默認的瀏覽器窗體滾動事件仍是綁定在window對象上。

3. 窗體的滾動高度獲取

如何獲取窗體的滾動高度呢?常見的有下面3種代碼:

window.pageYOffset;
document.documentElement.scrollTop;
document.body.scrollTop;複製代碼

都是有效的嗎?

咱們不妨測試下,想辦法識別此二維碼:

滾動高度二維碼

或者直接訪問這個頁面:3種窗體滾動高度獲取方法測試demo

結果在PC上是這樣:

PC上滾動高度識別

而在手機上則是:

滾動高度獲取移動端截圖

能夠看到桌面瀏覽器和移動端瀏覽器對於滾動高度獲取是有差異的,桌面端瀏覽器不能使用document.body.scrollTop獲取瀏覽器窗體的滾動高度,而移動端不能使用document.documentElement.scrollTop獲取瀏覽器窗體的滾動高度。可是都支持window.pageYOffset

因此,理論上講,瀏覽器窗體的滾動高度獲取使用window.pageYOffset便可,然而window.pageYOffset有一個缺點,就是IE9及其以上瀏覽器才支持,在PC端,不少項目是須要兼容IE8瀏覽器的,所以,對於傳統PC網站,獲取瀏覽器窗體滾動高度比較好的表達方法是這樣:

var winScrollTop = window.pageYOffset || document.documentElement.scrollTop;複製代碼

3. 瀏覽器窗體高度獲取

這個可使用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,你們能夠特殊記憶下。

4. 普通元素的滾動和高度獲取

普通元素的滾動直接添加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也是高度獲取,不會能夠是小數,特殊場景挺有用的。

3、答題核心概要總結

  1. 窗體滾動使用window.addEventListener,document有人反饋不反應;
  2. 窗體滾動滾動高度獲取:window.pageYoffset(IE9+),
    document.documentElement.scrollTop(PC),document.body.scrollTop(Mobile);
  3. 普通元素直接scrollTop;
  4. 窗體高度獲取:window.innerHeight(IE9+),
    備選方法爲:document.documentElement.clientHeight;
  5. 普通元素高度獲取:本題滾動事件中使用clientHeight(不含邊框,滾動是在border-box裏面的),
    offsetHeight包含邊框,可是是整數;
    getBoundingClientRect().height也包含邊框,但是是小數。(全部這幾個高度相關API都兼容IE6+)

重要參考文檔

本文提到的pageYoffset,innerHeight,clientHeight,offsetHeight,getBoundingClientRect等原生API都屬於CSSOM視圖模式(CSSOM View Module)相關內容,本文這裏只是一部分,更多內容能夠參見本站經典文章:「CSSOM視圖模式(CSSOM View Module)相關整理」。

下次直播預告

下週三羣裏發佈CSS小測第2期正常,可是因爲週六上班,有恰逢春節,所以直播答疑推遲到年後。想加入個人粉絲羣的能夠加我微信好友 zhangxinxu-job,我拉大家進去,備註「入羣」,而後附上大家的姓名,方便我備註。

(完)

相關文章
相關標籤/搜索