判斷DOM元素是否出現再瀏覽器窗口中

幾乎全部的項目都要解決這樣一個問題:判斷一個元素是否出如今瀏覽器窗口中?由於經過它咱們能夠極大的優化項目的性能,進而提高用戶的的體驗。javascript

使用場景及技術分析

所涉及的業務實現,比較常見的就是電商平臺或者是圖片展現類的網站。電商網站,如:淘寶京東等;圖片展現類,如:花瓣pinterestcss

涉及的技術,如:lazyload技術動態的加載圖片(元素),無限加載技術,包括基於骨架屏技術加載靜態資源。前端

  • 懶加載(lazyload):它目的是按需加載,而很大一部分項目的前端實現是經過判斷一個元素是否出如今瀏覽器窗口中,若是出現則將img元素標籤內的src屬性中的圖片地址替換成自定data-src屬性的地址,但這裏不必定是data-src屬性,也多是srcsetpinterest中就是這樣作的,固然你也能夠定義成任何你喜歡的,這只是其中的一種方式;另外一種是判斷元素是否出如今瀏覽器窗口中以後,而後加載一個HTML代碼塊,小米商城官網就是這樣實現的,固然也有其餘一些也是這樣作的,這裏就不一一作介紹了。
  • 無限加載(infinte scroll):它是經過底部的 加載更多 這個代碼塊是否出如今瀏覽器窗口中,若是在,就向容器代碼塊中追加必定數量的相關代碼塊,這時 加載更多 這個代碼塊就會被擠壓出到瀏覽器窗口以外。固然有些無限加載技術也使用lazyload。
  • 骨架屏技術(skelton screen):這個技術在前一波廣受關注,它的原理就是在請求一個頁面時,先不顯示頁面的內容,先顯示頁面的佈局,像文字、圖片、視頻等靜態資源都不顯示,而顯示的是與頁面佈局相關的css樣式。其實通俗一點來講,就是網頁作一個CT,這樣是否是理解起來更方便?像淘寶的pc官網,youtube都是這樣實現的。

這些業務和技術的目的都是爲了爲了解決低網速狀況下使用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.offsetTopwindow.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) {}

雖然這種方法也能夠,但它的瀏覽器兼容性不如第一種。

參考資料

相關文章
相關標籤/搜索