原因(简略版):为了减轻服务器的压力并提高用户体验
原理:当图片进入到可视区域时再给 img 标签 赋 src 属性,img 有 src 属性后才会向服务器发送请求。
**********************
为了同一目的可能需要的用到的:
在线压缩图片的网站
1.一次上传20张,转换的图片文件名保持一致,单张图片最大不能超过5MB,目前使用下来还没有超过限制过
TinyPNG – Compress WebP, PNG and JPEG images intelligently
转换图片格式的
1.可一次性上传10个文件,转换文件名称不变
JPG、PNG、BMP转WEBP-在线图片格式转换成WEBP-改图鸭
2.可一次性上传7个文件,转换的图片文件名不会改变,使用下来一天大概限制30张图片(超出限制他会直接错误提示ERROR UPLOADING FILE)
在线将JPG 转换成 WEBP 。 免费将.JPG 转换成.WEBP 。
3.可一次性上传5个文件,转换的图片会改变文件名,原始文件名会被夹在中间,限制图片比30张少的样子,具体记不太清了
jpg_webp | PDF转Word | 免费在线PDF转Word | PDF转Word转换器 | PDF转化速度快
4.图片需要一张一张上传,转换后的文件名看不出什么规律,适合其他网站免费张数用完了备用
**********************
懒加载部分
一.img 标签部分
<img
data-content-large-src="./images/1920-01.jpg"
data-content-small-src="./images/1080-01.jpg"
class="content-img-lazyLoad"
src="./images/64a657a4194edad4f98ef828840b904d.gif">
<img
data-content-large-src="./images/1920-02.jpg"
data-content-small-src="./images/1080-02.jpg"
class="content-img-lazyLoad"
src="./images/64a657a4194edad4f98ef828840b904d.gif">
首先给 img 一个自定义的属性保存正确的 src 地址
1.监听scroll判断图片是否在可视区域内
function contentImgLazyLoad(imgSelector) {
const clientHeight = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, // 兼容获取
scrollTop = document.documentElement.scrollTop; // 获取页面被卷出去的顶部的高度大小
// 这边通过传标签获取加载的图片列表
let imgsNodes = document.querySelectorAll(imgSelector);
// 遍历检查图片是否在可视区内
imgsNodes.forEach((v) => {
if (
v.offsetTop < clientHeight + scrollTop &&
v.offsetTop + v.offsetHeight > scrollTop
) {
// 赋值
if ( document.body.scrollWidth > 1200) {
v.src = v.getAttribute("data-vp-content-large-src");
} else {
// if ( 769 < document.body.scrollWidth <= 1080)
v.src = v.getAttribute("data-vp-content-small-src");
}
}
});
}
window.onload = function(){
//先执行一遍
contentImgLazyLoad('img')
//监听 scroll 并执行
window.addEventListener('scroll',contentImgLazyLoad.bind(this,'img'))
}
2. Intersection Observer API 交叉观察器”,可以自动判断元素是否在可见区域内,提供一个图片可见后的回调函数,在回调函数中赋值即可。
var images = document.querySelectorAll(imgSelector);
function callback(entries) {
for (let i of entries) {
if (i.isIntersecting) {
let img = i.target;
let trueSrc = img.getAttribute("data-vp-content-large-src");
img.setAttribute("src", trueSrc);
observer.unobserve(img); //停止观察,这样来回滚动后也只用加载一次
}
}
}
const observer = new IntersectionObserver(callback);
for (let i of images) {
observer.observe(i);//给每张图片绑定一个观察器
}
window.onload = function(){
contentImgLazyLoad('img') // 先执行
}
**********
总结部分
1.监听scroll的话会加载很多遍,有看到说用闭包可以解决这个问题,但是因为还没实践就不放上来了
2.Intersection Observer API 的话不可以像自己判断高度那样提前10px控制图片预先加载出来,所以可能会出现白屏等影响体验的部分,另外这个API兼容性不是很好,IE和Safari不支持
大家看自己需求选择吧,后面可能会补充 js 转换图片格式为 webp 的部分
The End