前言
一直以來,檢測元素在瀏覽器視視窗內不是件容易的事,很多解決方案都不能很準確的判斷,計算量也有可能拖慢網站效能。 但是很多場景都需要用到:
- 當頁面滾動時,懶載入圖片或其他內容。
- 實現“可無限滾動”網站,也就是當使用者滾動網頁時直接載入更多內容,無需翻頁。
- 為計算廣告收益,檢測其廣告元素的曝光情況。
- 根據使用者是否已滾動到相應區域來靈活開始執行任務或動畫。
通常檢測是否在視窗內原理
監聽瀏覽器滾動事件scroll
,對每個目標元素執行Element.getBoundingClientRect(),getBoundingClientRect
方法返回元素的大小及其相對於視口的位置。 此方法可獲取整個網頁左上角定位 ,及距瀏覽器頂部的或左側的距離,然後用innerHeight
、innerwidth
等得到視窗大小,以此相減來判斷是否在視窗範圍內。
具體程式碼如下:codepen.io/raoenhui/pe…
還有其他檢測原理大多都是通過計算得到,但是下面我將要介紹由瀏覽器自帶方法檢測元素是否在視窗內。
新檢測原理Intersection observer
Intersection observer 允許你配置一個回撥函式,每當target
進入瀏覽器視窗時,觸發回撥函式。
原始碼地址:codepen.io/raoenhui/pe…
用法
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 回撥函式
案例
原始碼地址:codepen.io/raoenhui/pe…
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
支援性不好,用到的小夥伴們要注意這點了,相容性具體看下圖:
其他連結
Happy coding .. :)