方式一: 分批加载图片
在页面加载时,接口返回或者手动将img标签的src属性设置为默认的占位图片,将图片的真实地址放在data-src属性上,再根据批量加载的频率,每隔一定时间,将部分img的src的内容设置为真实地址,直到全部替换。
此方式是在实现根据判断Img是否位于可视窗口内来加载图片较复杂的一种折中方式。通过requestAnimationFrame决定替换的时机,设定的是一秒加载2张图片。
lazyLoadImg() { let count = 0; let idx = 0; let frame; this.isDomLoaded =false; const replaceImgSrc = () => { frame = window.requestAnimationFrame(replaceImgSrc); if (count % 30 === 0) { const container = document.querySelector(`#container`); if (!container) { return; } const lazyImages = container.querySelectorAll('img[data-src]'); if (idx === this.existsImgUrls.length) { window.cancelAnimationFrame(frame); return; } if (lazyImages.length) { lazyImages[idx].setAttribute("src", this.existsImgUrls[idx]); idx++; } } count++; } frame = window.requestAnimationFrame(replaceImgSrc); }
方式二: 只加载位于可视窗口中的图片
原理与方式一相同,都是先将图片的真实地址存放在data-src属性上,只是只有当元素处于可视范围中时才加载图片,在加载图片的时机上与方式一有区别。
const imgs = document.getElementsByTagName("img"); const viewHeight = window.innerHeight || document.documentElement.clientHeight; let num = 0;function lazyLoad() { for (let i = num; i < imgs.length; i++) { // 用可视区域高度减去元素顶部距离可视区域顶部的高度 let distance = viewHeight - imgs[i].getBoundingClientRect().top; // 如果可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明元素露出 if (distance >= 0) { // 给元素写入真实的src,展示图片 imgs[i].src = imgs[i].getAttribute("data-src"); // 前i张图片已经加载完毕,下次从第i+1张开始检查是否露出 num = i + 1; } } } window.addEventListener('scroll', lazyLoad, false); // 此处需要使用防抖函数进行优化 复制代码
方式三: 使用Intersection Observer API
此方法在IE上不支持,如果要考虑IE浏览器时需要考虑兼容性。
document.addEventListener("DOMContentLoaded", function() { let lazyImages = [...document.querySelectorAll('.lazy-load')]; if ("IntersectionObserver" in window) { // 创建一个观察函数,以便待会调用 let lazyImageObserver = new IntersectionObserver(function(entries, observer) { entries.forEach(function(entry) { if (entry.isIntersecting) { let lazyImage = entry.target; lazyImage.src = lazyImage.dataset.src; // 替换 src URL lazyImageObserver.unobserve(lazyImage); // 解除观察 } }); }); // 对所有需要懒加载的图片进行 “暗中观察” lazyImages.forEach(function(lazyImage) { lazyImageObserver.observe(lazyImage); }); }else{ alert('您的浏览器不支持 IntersectionObserver'); } });
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END