日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Html图片懒加载动画,Intersection Observer实现滚动到相应区域执行动画及图片懒加载...

發(fā)布時間:2024/1/23 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Html图片懒加载动画,Intersection Observer实现滚动到相应区域执行动画及图片懒加载... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Intersection observer API提供了一種方法,可以異步觀察目標元素與祖先元素或相對于瀏覽器視口(root)的交集變化。

很多種情況下都需要用到元素交集變化的信息,例如:當頁面滾動時,懶加載圖片或其他內(nèi)容。

實現(xiàn)“可無限滾動”網(wǎng)站,也就是當用戶滾動網(wǎng)頁時直接加載更多內(nèi)容,無需翻頁。

為計算廣告收益,檢測其廣告元素的曝光情況。

根據(jù)用戶是否已滾動到相應(yīng)區(qū)域來靈活開始執(zhí)行任務(wù)或動畫。

過去,交集檢測通常需要涉及到事件監(jiān)聽,以及對每個目標元素執(zhí)行Element.getBoundingClientRect()方法以獲取所需信息??墒沁@些代碼都在主線程上運行,所以任何一點都可能造成性能問題。

一睹為快:var options = {

root: document.querySelector('#scrollArea'),

rootMargin: '0px',

threshold: 1.0

}

var callback = function(entries, observer) {

entries.forEach(entry => {

//以下都是只讀屬性

entry.time; // 返回一個記錄從 IntersectionObserver 的時間原點(time origin)到交叉被觸發(fā)的時間的時間戳(DOMHighResTimeStamp).

entry.rootBounds; // 返回一個 DOMRectReadOnly 用來描述交叉區(qū)域觀察者(intersection observer)中的根.

entry.boundingClientRect; // 返回包含目標元素的邊界信息的DOMRectReadOnly. 邊界的計算方式與 Element.getBoundingClientRect() 相同..

entry.intersectionRect; // 返回一個 DOMRectReadOnly 用來描述根和目標元素的相交區(qū)域.

entry.intersectionRatio; // 返回intersectionRect 與 boundingClientRect 的比例值.

entry.target; // 與根出現(xiàn)相交區(qū)域改變的元素 (Element).

});

};

//通過new IntersectionObserver()構(gòu)造器創(chuàng)建并返回一個IntersectionObserver實例對象。

var observer = new IntersectionObserver(callback, options);

var target = document.querySelector('#listItem');

//為觀察者對象添加一個觀察元素

observer.observe(target);

callback

當元素可見比例超過指定閾值后,會調(diào)用一個回調(diào)函數(shù),此回調(diào)函數(shù)接受兩個參數(shù):entries:一個IntersectionObserverEntry對象列表(list),每個被觸發(fā)的閾值,都會較指定閾值有偏差(或超出或少于指定閾值)。

observer:被調(diào)用的IntersectionObserver實例對象。

options可選

一個可以用來配置observer實例的對象。如果options未指定,observer實例默認使用viewport作為根(root),并且沒有margin, 閾值為0% (意味著即使1像素的改變都會觸發(fā)回調(diào)函數(shù))。你可以指定以下配置:root:監(jiān)聽元素的祖先元素Element對象,其邊界盒將被視作viewport。目標在根的可見區(qū)域的的任何不可見部分都會被視為不可見。如果設(shè)置root參數(shù)為null或者不設(shè)置則root默認為設(shè)備視口)。

rootMargin:一個在計算交叉值時添加至根的邊界盒(bounding_box)中的一組偏移量,類型為字符串(string) ,可以有效的縮小或擴大根的判定范圍從而滿足計算需要。語法大致和CSS 中的margin屬性等同:上、右、下、左。默認值是"0px 0px 0px 0px".

threshold:規(guī)定了一個監(jiān)聽目標與邊界盒交叉區(qū)域的比例值,可以是一個具體的數(shù)值或是一組0.0到1.0之間的數(shù)組。若指定值為0.0,則意味著監(jiān)聽元素即使與根有1像素交叉,此元素也會被視為可見. 若指定值為1.0,則意味著整個元素都是可見的。閾值的默認值為0.0.

IntersectionObserver實例對象方法IntersectionObserver.disconnect:使IntersectionObserver對象停止監(jiān)聽工作。

IntersectionObserver.observe:使IntersectionObserver開始監(jiān)聽一個目標元素。

IntersectionObserver.takeRecords:為所有監(jiān)聽目標返回一個IntersectionObserverEntry對象數(shù)組并且停止監(jiān)聽這些目標。

IntersectionObserver.unobserve:使IntersectionObserver停止監(jiān)聽特定目標元素。

滾動到相應(yīng)區(qū)域執(zhí)行css動畫

....

....

const addAnimation = function(){

const observerEle = function(){

//選取元素

const elements = document.querySelectorAll('.b-block');

const options = {};

let imageCount = elements.length;

const observer = new IntersectionObserver(onIntersection,options);

Array.prototype.slice.call(elements).forEach(target=>{

//給選取的元素添加監(jiān)聽目標

observer.observe(target);

});

function onIntersection(entries,observer){

//終止對所有目標的監(jiān)聽觀察

if (imageCount === 0) {

observer.disconnect();

}

entries.forEach(entry=>{

//entry.intersectionRatio = 1在視口內(nèi),0為不在視口內(nèi)

//也可以試一試entry.isIntersecting為true在視口內(nèi),為false為不在視口內(nèi)

if (entry.intersectionRatio > 0) {

imageCount--;

//停止監(jiān)聽當前目標元素

observer.unobserve(entry.target);

//給目標元素添加css動畫類名

entry.target.classList.add('transition');

}

});

}

};

if('IntersectionObserver' in window ) observerEle();

}();

瀏覽器兼容的圖片懶加載var lazyLoad = function() {

var IeModule = function(){

var map_element = {},

element_obj = [],

download_count = 0,

last_offset = -1,

doc = document,

doc_body = doc.body,

doc_element = doc.documentElement,

lazy_load_tag = "img",

imagesrcname = 'a',

thissrolltop = 400;

function initElementMap(){

var el = doc.getElementsByTagName(lazy_load_tag);

for (var j = 0, len2 = el.length; j < len2; j++) {

if (typeof el[j] == "object" && el[j].getAttribute(imagesrcname)){

element_obj.push(el[j]);

}

}

for (var i = 0, len = element_obj.length; i < len; i++) {

var o_img = element_obj[i],

t_index = getAbsoluteTop(o_img);

if (map_element[t_index]){

map_element[t_index].push(i);

}else{

var t_array = [];

t_array[0] = i;

map_element[t_index] = t_array;

download_count++;

}

}

}

function initDownloadListen(){

if (!download_count) return;

var getscrolltop = doc_body.scrollTop;

if(getscrolltop == 0){

getscrolltop = doc.documentElement.scrollTop;

}

var visio_offset = getscrolltop + doc_element.clientHeight;

if (last_offset == visio_offset){

setTimeout(initDownloadListen,200);

return;

}

last_offset = visio_offset;

var visio_height = doc_element.clientHeight + thissrolltop,

img_show_height = visio_height + getscrolltop;

// var allurlnum = parseInt(imageurlarray.length);

// if(allurlnum <= 0)

// {

// allurlnum = 1;

// }

var j = 0;

for (var key in map_element) {

if (img_show_height > key){

var t_o = map_element[key],

img_vl = t_o.length;

for (var l = 0; l < img_vl; l++) {

element_obj[t_o[l]].src = element_obj[t_o[l]].getAttribute(imagesrcname);

element_obj[t_o[l]].removeAttribute(imagesrcname);

j++;

}

delete map_element[key];

download_count--;

}

}

setTimeout(initDownloadListen, 200);

}

function getAbsoluteTop(element) {

if (arguments.length != 1 || element == null){

return null;

}

var offsetTop = element.offsetTop,

current = element.offsetParent;

while(current !== null){

offsetTop += current.offsetTop;

current = current.offsetParent;

}

return offsetTop;

}

function init(){

initElementMap();

initDownloadListen();

}

init();

},

observerImg = function(){

// 獲取所有標記為懶惰加載的圖像。

var images = document.querySelectorAll('img[a]'),

config = {//如果圖像在y軸內(nèi)達到上下50px,則開始下載。

rootMargin: '50px 0px',

threshold: 0.01

},

imageCount = images.length,

observer = new IntersectionObserver(onIntersection, config);

Array.prototype.slice.call(images).forEach(function(target){

observer.observe(target);

});

function onIntersection(entries) {

//終止對所有目標的觀察

if (imageCount === 0) {

observer.disconnect();

}

entries.forEach(function(entry){

//1在視口內(nèi),0為不在視口內(nèi)

if (entry.intersectionRatio > 0) {

imageCount--;

//停止觀察并載入圖像

observer.unobserve(entry.target);

preloadImage(entry.target);

}

});

}

function fetchImage(url) {

return new Promise(function(resolve, reject){

var image = new Image();

image.src = url;

image.onload = resolve;

image.onerror = reject;

});

}

function preloadImage(image) {

//const src = image.dataset.src;

var src = image.getAttribute("a");

if(!src) return;

return fetchImage(src).then(function(){ applyImage(image, src); });

}

function applyImage(img, src) {

// Prevent this from being lazy loaded a second time.

// img.classList.add('js-lazy-image--handled');

img.src = src;

img.classList.add('fade-in');

img.removeAttribute("a");

}

};

//如果我們沒有支持交叉路口觀察員,立即加載圖像

if('IntersectionObserver' in window ){

observerImg();

return;

}

IeModule();

}()

總結(jié)

以上是生活随笔為你收集整理的Html图片懒加载动画,Intersection Observer实现滚动到相应区域执行动画及图片懒加载...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。