幾乎全部的項目都要解決這樣一個問題:判斷一個元素是否出如今瀏覽器窗口中?由於經過它咱們能夠極大的優化項目的性能,進而提高用戶的的體驗。javascript
所涉及的業務實現,比較常見的就是電商平臺或者是圖片展現類的網站。電商網站,如:淘寶、京東等;圖片展現類,如:花瓣,pinterest。css
涉及的技術,如:lazyload技術動態的加載圖片(元素),無限加載技術,包括基於骨架屏技術加載靜態資源。前端
data-src
屬性的地址,但這裏不必定是data-src
屬性,也多是srcset
,pinterest中就是這樣作的,固然你也能夠定義成任何你喜歡的,這只是其中的一種方式;另外一種是判斷元素是否出如今瀏覽器窗口中以後,而後加載一個HTML代碼塊,小米商城官網就是這樣實現的,固然也有其餘一些也是這樣作的,這裏就不一一作介紹了。加載更多
這個代碼塊是否出如今瀏覽器窗口中,若是在,就向容器代碼塊中追加必定數量的相關代碼塊,這時 加載更多
這個代碼塊就會被擠壓出到瀏覽器窗口以外。固然有些無限加載技術也使用lazyload。這些業務和技術的目的都是爲了爲了解決低網速狀況下使用web應用,若是頁面內內容沒有加載,那麼就會形成低用戶體驗。java
這些業務和使用的技術基本上都用了 判斷頁面的元素是否出如今瀏覽器窗口中
。jquery
如今通用的是基於瀏覽器的窗口的判斷
那麼何爲基於瀏覽器窗口的判斷呢?這要經過DOM的API .getBoundingClientRect()
,獲取目標元素距離瀏覽器窗口的位置座標(top, left) 或者(x, y)座標,因此說是基於瀏覽器窗口的。咱們能夠拖動瀏覽器的滾動條來使目標元素從瀏覽器的頂端進入瀏覽器窗口(這能夠判斷上邊界),也能夠從瀏覽器的底部進入瀏覽器窗口(這能夠判斷下邊界),而這正好是判斷目標元素進入瀏覽器窗口的邊界。git
上邊界:github
目標元素的底邊恰好和瀏覽器的頂部重合,當滾動條向下滾動,目標元素從底部開始一點點的出現,直到目標元素整個出如今瀏覽器窗口,反之,則逐漸遠離。若是目標元素高度大於瀏覽器窗口的高度,那麼瀏覽器窗口內就不不出現整個目標元素,而只會出現部分,基於這種狀況衍生了一種目標元素背景圖片的滾動動畫。可參考蘋果官網。web
下邊界:瀏覽器
目標元素的頂部恰好和瀏覽器的底部重合,當滾動條向上滾動,目標元素從頂部部開始一點點的出現,直到目標元素整個出如今瀏覽器窗口,反之,則逐漸遠離。app
咱們能夠瀏覽器的滾動條向下滾動(也能夠按照向下滾動,答案相似)寫出以下的代碼:
var clienRect = el.getBoundingClientRect(); if (clientRect.top > -clientRect.width && clientRect.top < window.innerHeight) {} // 或者 if (clientRect.bottom > 0 && clientRect.top =< window.innerHeight) {}
有的同窗可能會問,是否是窗口的高度小於目標元素的高度,或者窗口的高度大於目標元素的高度都這樣都同樣呢?我想說同樣,由於這裏是根據兩個邊界得出的結論。
上面的判斷包括目標元素的部分出如今瀏覽器窗口,那麼如何判斷整個目標元素出如今瀏覽器的窗口中呢?可參考以下的代碼:
var clienRect = el.getBoundingClientRect(); if (clientRect.top > 0 && clientRect.top < window.innerHeight - clientRect.width) {} // 或者 if (clientRect.top >= 0 && clientRect.bottom > window.innerHeight) {}
兼容性可參考can i use
基於document文檔的頂部來判斷
這裏要使用的是DOM元素的 .offsetTop
來計算目標元素的頂部邊界到document文檔的頂部邊界的距離,使用window的 .pageYoffset
來計算當瀏覽器滾動條滾動時document文檔卷起的高度,經過比較這兩個高度,咱們就能夠輕鬆的判斷目標元素是否出如今瀏覽器窗口內。
當目標元素的上邊界和瀏覽器窗口的下邊界重合,目標元素的 offsetTop
是個定值,因此此時document文檔卷起的高度和目標元素的 offsetTop
之間存在這樣一個等式:window.innerHeight + window.pageYoffset = el.offsetTop
。若繼續向下滾動瀏覽器的滾動條,目標元素將出如今瀏覽器當中,咱們都知道 window.pageYoffset
的值將繼續變大,因爲 el.offsetTop
和 window.innerHeight
都是個定值,因此咱們能夠獲得這樣一個邊界條件,當 window.pageYoffset > el.offsetTop - window.innerHeight
,目標元素從瀏覽器窗口的底部逐漸出現。
當瀏覽器的滾動條繼續向上滾動會出現目標元素的下邊界和瀏覽器窗口的上邊界重合的狀況,當繼續向下滾動滾動條元素將從瀏覽器窗口消失,此時存在這樣一個等式:window.pageYoffset + el.offsetHeight = el.offsetTop
,因此很明顯,若是 window.pageYoffset
的值繼續增大,目標元素將消失與瀏覽器窗口,所以,很明顯,只有 window.pageYoffset < el.offsetTop - el.offsetHeight
目標元素纔會出如今瀏覽器窗口內。
參考代碼以下:
if (window.pageYoffset > el.offsetTop - window.innerHeight && window.pageYoffset < el.offsetTop - el.offsetHeight) {}
固然,上面的是目標元素部分或總體出如今瀏覽器窗口的判斷條件,若是是整個目標元素,方法同上,可參考下面的代碼:
if (window.pageYoffset > el.offsetTop - window.innerHeight - el.offsetHeight && window.pageYoffset < el.offsetTop) {}
雖然這種方法也能夠,但它的瀏覽器兼容性不如第一種。