# 懒加载实例

  1. 位置计算 + 滚动事件 (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" />
最后更新: 9/4/2022, 9:30:25 AM