图片懒加载方案

方案1:监听滚动事件

Document* {margin: 0;padding: 0;}html,body {width: 100%;height: 100%;}.box {height: 100%;overflow-y: auto;}.ele1 {height: 1200px;width: 100%;background-color: goldenrod;}.ele2 {height: 300px;width: 100%;margin-top: 20px;background-color: skyblue;}

目标元素距离顶部的距离 < 可视区域;就说明需要加载图片

Element.getBoundingClientRect() 方法可以返回一个对象,其提供了元素的大小及其相对于视口的位置

{ bottom: 1441; height: 300; left: 0; right: 965; top: 1141; width: 965; x: 0; y: 1141 }

其中 widthheight属性是包含了 paddingborder-width

const lazyImgs = document.querySelectorAll(".lazy-img");const screenHeight = window.innerHeight;document.querySelector(".box").addEventListener("scroll", () => {lazyImgs.forEach((img) => {if (img.getBoundingClientRect().top < screenHeight) {const dataSrc = img.getAttribute("data-src");const isLoading = img.getAttribute("src");!isLoading && img.setAttribute("src", dataSrc);}});});

方案2:Object.IntersectionObserver

语法:创建一个observer观察实例,可以使用observe方法观察具体的dom

const observer=new IntersectionObserver(callback,option)

callback函数

目标元素刚好被看到、刚好消失是都会触发 callback 回调

entries是一个数组,数组中是被观察的dom信息

(entries)=> {}

option

观察dom节点和取消观察

observer.observe(DOM节点)observer.unobserve(DOM节点)

具体实现

const observer = new IntersectionObserver((entries) => {entries.forEach((entry) => {// 如果图片进入可视区域,设置src属性获取图片资源if (entry.isIntersecting) {// const img = entry.target;// const dataSrc = img.getAttribute("data-src");// img.setAttribute("src", dataSrc);entry.target.src = entry.target.dataset.src;observer.unobserve(entry.target); // 获取后取消对该图片的观察}});});const lazyImgs = document.querySelectorAll(".lazy-img");// 观察所有图片lazyImgs.forEach((img) => {observer.observe(img);});