# 懒加载实例
- 位置计算 + 滚动事件 (Scroll) + DataSet API
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<div class="di<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
img{
display: block;
width: 700px;
height: 700px;
}
</style>
</head>
<body>
<ul class="img-group">
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
<li><img src="apple.jpg" data-src="12.jpg"></li>
</ul>
<script type="text/javascript">
let imgArr = document.querySelectorAll('img');
let len = imgArr.length;
let n = 0; //记录加载图片的位置,避免从第一张开始加载
let canrun = true;
let seeHeight = document.documentElement.clientHeight;
lazyLoad();
window.onscroll = function () {
if(!canrun){
return ;
}
canrun = false;
setTimeout(function () {
console.log('*****');
lazyLoad();
canrun= true;
},1000);
}
function lazyLoad() {
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log("scrollTop ="+scrollTop);
for(let i=0; i<len; i++){
console.log(imgArr[i].offsetTop);
if(imgArr[i].offsetTop < seeHeight + scrollTop){
if(imgArr[i].getAttribute('src')=='apple.jpg'){
imgArr[i].src = imgArr[i].getAttribute('data-src');
}
n = i+1;
console.log("n="+n);
}
}
}
</script>
</body>
</html>
注意 imgArr[i].getAttribute('src')=='apple.jpg'根据实际自行替换
<img data-src="shanyue.jpg" />
img.src = img.datset.src
# getBoundingClientRect
方案2:[getBoundingClientRect API + Scroll with Throttle + DataSet API]
Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。
// clientHeight 代表当前视口的高度
img.getBoundingClientRect().top < document.documentElement.clientHeight;
# 懒加载IntersectionObserver 虚拟列表
方案三 IntersectionObserver
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<style>
img{
display: block;
width: 300px;
height: 300px;
border: 1px solid #ccc;
margin-bottom: 20px;
padding: 1px;
}
.imgFade {
transition: 0.6s opacity;
-webkit-animation: fadeIn 0.6s linear;
animation: fadeIn 0.6s linear;
}
@-webkit-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
<img src="https://images.dog.ceo/breeds/samoyed/n02111889_16414.jpg" data-src="https://13799942.s61i.faiusr.com/2/AD0IhqTKBhACGAAglpb0yAUoraL29wcw_QI49wE.jpg">
</body>
<script>
function showImg(element, imgObserver) {
let relPath = $(element).attr("data-src");
// imgFade是图片动画Class
$(element).attr("src", relPath).addClass("imgFade");
// 显示图片之后解除监听
imgObserver.unobserve(element);
}
// 注册检查器
let imgObserver = new IntersectionObserver((entries) => {
// console.log(1)
entries.forEach((val) => {
// isIntersecting标记元素是否进入可视区域
if (val && val.isIntersecting && val.target) {
let target = $(val.target);
// 加载图片
showImg(val.target, imgObserver);
}
})
},{
root: null, // 默认值为null,也就是视口区域,表示监听的可视区域为整个视口,也就是浏览器的可视区域
threshold: [0], // 属性决定了什么时候触发回调函数。默认为[0] 比如,[0, 0.25, 0.5, 0.75, 1]就表示当目标元素 0%、25%、50%、75%、100% 可见时,会触发回调函数。
rootMargin: '0px' // 定义根元素的margin,用来扩展可视区的范围,或者可以这样理解,root元素,多了一个margin属性,如果没有这个margin属性,ele元素只有与root元素开始交叉时才会触发可视性的变化,而这个rootMargin属性的话,就是当ele元素与root元素的外边距交叉时,就会触发ele元素的可视性变化。
});
$("img").each((index, val) => {
imgObserver.observe(val);
});
</script>
</html>
方案4:浏览器img标签自带属性
<img src="shanyue.jpg" loading="lazy" />