JavaScript实现图片懒加载的三种方案详解
作者:起风了啰
图片懒加载,当图片出现在可视区域再进行加载,提升用户的体验,这篇文章主要为大家整理了三个常用的图片懒加载实现方法,希望对大家有所帮助
一、前言
图片懒加载,当图片出现在可视区域再进行加载,提升用户的体验。因为有些用户不会看完图片,全部加载会浪费流量。在网上查阅资料,总结了三种办法,有各自的利弊,下文一一介绍。
方法 | 优点 | 缺点 | 推荐指数 |
---|---|---|---|
设置img loading | h5的属性,没有兼容问题 | 需要已知图片高度、宽高比 | ⭐️⭐️ |
IntersectionObserver API | 无需知道图片高度 | 低版本需引入polyfill | ⭐️⭐️⭐️ |
vue-lazyload 自定义指令 | 无需知道图片高度 | github现存issues较多,没有解决 | ⭐️⭐️ |
二、实现方式及Demo
1. 设置img标签loading属性
loading属性允许两个值:eager
立即加载图像(默认值);lazy
延迟加载图像。在使用lazy属性的时候,需要设置<img>
标签的高度,否则无法懒加载。
注意: 适用于两种场景,图片高度已知、图片宽高比已知。
已知图片高度
<style> .img-box img { width: 100%; height: 700px; /*设置为图片的真实高度*/ } </style> <div class="img-box"> <img src="https://i.postimg.cc/GtN3Cs02/1.jpg" loading="lazy" /> <img src="https://i.postimg.cc/hGdKLGdW/2.jpg" loading="lazy" /> <img src="https://i.postimg.cc/T1SkJTbF/3.jpg" loading="lazy" /> <img src="https://i.postimg.cc/wxPFPTtb/4.jpg" loading="lazy" /> <img src="https://i.postimg.cc/FRkGF28x/5.jpg" loading="lazy" /> <img src="https://i.postimg.cc/05JH9wqq/6.jpg" loading="lazy" /> </div>
已知图片宽高比
<style> .img-box div { position: relative; padding-top: 66%; /* (你的图片的高度/宽度值) */ overflow: hidden; } .img-box img { position: absolute; top:0; right:0; width:100%; } </style> <div class="img-box"> <div> <img src="https://i.postimg.cc/GtN3Cs02/1.jpg" loading="lazy" /> </div> <div> <img src="https://i.postimg.cc/hGdKLGdW/2.jpg" loading="lazy" /> </div> <div> <img src="https://i.postimg.cc/T1SkJTbF/3.jpg" loading="lazy" /> </div> <div> <img src="https://i.postimg.cc/wxPFPTtb/4.jpg" loading="lazy" /> </div> <div> <img src="https://i.postimg.cc/FRkGF28x/5.jpg" loading="lazy" /> </div> <div> <img src="https://i.postimg.cc/05JH9wqq/6.jpg" loading="lazy" /> </div> </div>
2. 使用 IntersectionObserver
IntersectionObserver接口,可以观察DOM节点是否出现在视口,当DOM节点出现在视口中才加载图片。img必须有高度,否则图片默认都在视口中,会将图片全部加载。可以设置img的src为base64白色图片,然后在替换为真实的图片地址。
注意: 不需要预先知道图片的高度,但是有兼容性问题,低版本需要引入intersection-observer polyfill
已知图片高度
<style> .img-box .lazy-img { width: 100%; height: 600px; /*如果已知图片高度可以设置*/ } </style> <div class="img-box"> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/d48aed7c991b43d850d011f2299d852e.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/a588b152c79ac60162ecbdf82b060061.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/eacbc2cd4b6ca636077378182bdfcc88.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/751470f4b478450e8556f78cd7dd3d96.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/e4a531bee5694a4a01dee74b18bbfd8b.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/7d8f107e827a7beaa0b9d231bfa4187f.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/4f7586f6b74f2bd0b94004fcbae69856.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/863849e14e7e8903ed4b27fcbdafe8b0.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/d8bb17fe9a7223f35075014ef250e2fa.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/> </div> <script> function Observer() { let images = document.querySelectorAll(".lazy-img"); let observer = new IntersectionObserver(entries => { entries.forEach(item => { if (item.isIntersecting) { item.target.src = item.target.dataset.origin; // 开始加载图片,把data-origin的值放到src observer.unobserve(item.target); // 停止监听已开始加载的图片 } }); }); images.forEach(img => observer.observe(img)); } Observer() </script>
3. 使用vue-lazyload
在vue2中使用时,建议安装npm i vue-lazyload@1.3.3 -s
,使用高版本在main.js
中全局自定义指令后依然无法使用指令。在vue3中可以使用 npm i vue3-lazy -s
。
全局注册自定义指令,在页面就可以使用了
// 全局自定义指令 import Vue from 'vue' import VueLazyload from 'vue-lazyload' Vue.use(VueLazyload, { preLoad: 1, observer: true // 设置为true,内部使用IntersectionObserver。默认使用 })
/* 在页面中直接使用 */ <div> <img v-lazy="https://images.djtest.cn/pic/test/d48aed7c991b43d850d011f2299d852e.jpg"> <img v-lazy="https://images.djtest.cn/pic/test/a588b152c79ac60162ecbdf82b060061.jpg"> <img v-lazy="https://images.djtest.cn/pic/test/eacbc2cd4b6ca636077378182bdfcc88.jpg"> <img v-lazy="https://images.djtest.cn/pic/test/751470f4b478450e8556f78cd7dd3d96.jpg"> </div>
以上就是JavaScript实现图片懒加载的三种方案详解的详细内容,更多关于JavaScript图片懒加载的资料请关注脚本之家其它相关文章!