深圳电信网络建站,重庆网站建设在哪里,网站建设预算及准备,网站 wap前端面试题库 #xff08;面试必备#xff09; 推荐#xff1a;★★★★★
地址#xff1a;前端面试题库 表妹一键制作自己的五星红旗国庆头像#xff0c;超好看 最近开发了一个功能#xff0c;页面首页会加载大量的图片#xff0c;初次进入页面时#xff… 前端面试题库 面试必备 推荐★★★★★
地址前端面试题库 表妹一键制作自己的五星红旗国庆头像超好看 最近开发了一个功能页面首页会加载大量的图片初次进入页面时会导致页面性能下降
于是乎我改进了这个功能可以让所有图片自动懒加载。 原理
这个功能主要的底层逻辑是是使用IntersectionObserver APIIntersectionObserver用于在浏览器中观察元素的可见性和位置变化。它可以帮助开发者实现一些动态行为如图片的懒加载、无限滚动等。
简单的示例如下
// 创建IntersectionObserver实例
const observer new IntersectionObserver((entries, observer) {// 遍历观察的元素entries.forEach(entry {// 如果元素可见if (entry.isIntersecting) {// 加载图片const img entry.target;const src img.getAttribute(data-src);img.setAttribute(src, src);// 停止观察该元素observer.unobserve(img);}});
});// 获取所有需要懒加载的图片元素
const lazyImages document.querySelectorAll(.lazy-image);// 观察每个图片元素
lazyImages.forEach(image {observer.observe(image);
});实践
接下来我们实现一个通用的 hook基本的功能如下
给图片提供默认的占位图片 src同时提供data-src属性传入图片对应的 ref 属性。当图片进入可视区域时使用data-src属性替换 src 属性
import { onMounted, Ref } from vue;
const options {// root: document.querySelector(.container), // 根元素默认为视口rootMargin: 0px, // 根元素的边距threshold: 0.5, // 可见性比例阈值once: true,
};function callback(entries: IntersectionObserverEntry[],observer: IntersectionObserver
) {entries.forEach((entry) {// 处理每个目标元素的可见性变化if (entry.intersectionRatio 0) return;const img: Element entry.target;const src img.getAttribute(data-src);img.setAttribute(src, src ?? ); // 将真实的图片地址赋给 src 属性observer.unobserve(img);});
}export const useInView (ref: Ref) {const observer new IntersectionObserver(callback, options);onMounted(() {Object.keys(ref.value).forEach((e) observer.observe(ref.value[e]));});
};
script setup langts
import { ref } from vue;
import { useInView } from ./hooks/useInView;const imgRef ref(null);
useInView(imgRef);
/scripttemplateh4公众号萌萌哒草头将军/h4divv-for(_, idx) in new Array(200).fill(11)imgrefimgRefsrchttps://via.placeholder.com/200:data-srchttps://picsum.photos/200/${180 idx}altb//div
/template实际效果如下 虽然基本的功能要求已经完成了但是现在还不够优雅 优化
接下来我们增加个过渡动画。每次当加载完图片就从占位图过渡到正常图片模式。
img.onload () {img.setAttribute(class, fade-in)
}keyframes fadeIn {from {opacity: 0;}to {opacity: 1;}
}/* 应用淡入动画到元素 */
.fade-in {animation: fadeIn 0.6s ease-in;
}完整代码如下
import { onMounted, Ref } from vue;
const options {// root: document.querySelector(.container), // 根元素默认为视口rootMargin: 0px, // 根元素的边距threshold: 0.5, // 可见性比例阈值once: true,
};function callback(entries: IntersectionObserverEntry[],observer: IntersectionObserver
) {entries.forEach((entry) {if (entry.intersectionRatio 0) return;const img entry.target as HTMLImageElement;const src img.getAttribute(data-src);img.setAttribute(src, src ?? ); // 将真实的图片地址赋给 src 属性img.onload () {img.setAttribute(class, fade-in);};observer.unobserve(img);});
}export const useInView (ref: Ref) {const observer new IntersectionObserver(callback,options);onMounted(() {Object.keys(ref.value).forEach((e) observer.observe(ref.value[e]));});
};script setup langts
import { ref } from vue;
import { useInView } from ./hooks/useInView;const imgRef ref(null);useInView(imgRef);/scripttemplateh4公众号萌萌哒草头将军/h4divv-for(_, idx) in new Array(200).fill(11)stylewidth: 200px height: 200px;imgrefimgRefstyleheight: 100%srchttps://via.placeholder.com/200:data-srchttps://picsum.photos/200/${180 idx}altb//div
/templatestyle scoped
/* 定义淡入动画 */
keyframes fadeIn {from {opacity: 0;}to {opacity: 1;}
}/* 应用淡入动画到元素 */
.fade-in {animation: fadeIn 0.6s ease-in;
}
/style前端面试题库 面试必备 推荐★★★★★
地址前端面试题库 表妹一键制作自己的五星红旗国庆头像超好看