Intersection observer檢測元素是否在視窗內

前言

一直以來,檢測元素在瀏覽器視窗口內不是件容易的事,不少解決方案都不能很準確的判斷,計算量也有可能拖慢網站性能。 可是不少場景都須要用到:javascript

  • 當頁面滾動時,懶加載圖片或其餘內容。
  • 實現「可無限滾動」網站,也就是當用戶滾動網頁時直接加載更多內容,無需翻頁。
  • 爲計算廣告收益,檢測其廣告元素的曝光狀況。
  • 根據用戶是否已滾動到相應區域來靈活開始執行任務或動畫。

一般檢測是否在視窗內原理

監聽瀏覽器滾動事件scroll,對每一個目標元素執行Element.getBoundingClientRect(),getBoundingClientRect方法返回元素的大小及其相對於視口的位置。 此方法可獲取整個網頁左上角定位 ,及距瀏覽器頂部的或左側的距離,而後用innerHeightinnerwidth等獲得視窗大小,以此相減來判斷是否在視窗範圍內。java

具體代碼以下:codepen.io/raoenhui/pe…jquery

還有其餘檢測原理大多都是經過計算獲得,可是下面我將要介紹由瀏覽器自帶方法檢測元素是否在視窗內。git

新檢測原理Intersection observer

Intersection observer 容許你配置一個回調函數,每當target進入瀏覽器視窗時,觸發回調函數。 github

example1.gif

源碼地址:codepen.io/raoenhui/pe…chrome

用法

var options = {
    root: document.querySelector('#scrollArea'), 
    rootMargin: '0px', 
    threshold: 1.0
}
var callback = function(entries, observer) { 
    /* Content excerpted, show below */ 
};
var observer = new IntersectionObserver(callback, options);
複製代碼

參數

options 配置項數組

  • root 目標元素。默認使用瀏覽器視口作爲root
  • rootMargin root元素的外邊距。
  • threshold 閾值。能夠是單一的number也能夠是number數組,通常取1。

callback 回調函數瀏覽器

案例

example.gif

源碼地址:codepen.io/raoenhui/pe…app

target元素和root元素相交程度達到該值的時候IntersectionObserver註冊的回調函數將會被執行。 若是你只是想要探測當target元素的在root元素中的可見性超過50%的時候,你能夠指定該屬性值爲0.5。若是你想要target元素在root元素的可見程度每多25%就執行一次回調,那麼你能夠指定一個數組[0, 0.25, 0.5, 0.75, 1]。默認值是0(意味着只要有一個target像素出如今root元素中,回調函數將會被執行)。該值爲1.0含義是當target徹底出如今root元素中時候 回調纔會被執行。函數

插件jquery_lazyload懶加載就是用到了此方法,

源碼地址:github.com/tuupola/jqu…

this.observer = new IntersectionObserver(function(entries) {
                entries.forEach(function (entry) {
                    if (entry.intersectionRatio > 0) {
                        self.observer.unobserve(entry.target);
                        let src = entry.target.getAttribute(self.settings.src);
                        let srcset = entry.target.getAttribute(self.settings.srcset);
                        if ("img" === entry.target.tagName.toLowerCase()) {
                            if (src) {
                                entry.target.src = src;
                            }
                            if (srcset) {
                                entry.target.srcset = srcset;
                            }
                        } else {
                            entry.target.style.backgroundImage = "url(" + src + ")";
                        }
                    }
                });
            }, observerConfig);
複製代碼

兼容性

兼容性chrome基本支持,可是意外的是safari支持性很差,用到的小夥伴們要注意這點了,兼容性具體看下圖:

image.png

其餘連接

Happy coding .. :)

相關文章
相關標籤/搜索