图片懒加载方案
方案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 }
其中 width
和 height
属性是包含了 padding
和 border-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);});