当浏览器开始加载页面的时候,先不加载真实的图片(先用一张默认图占位),当页面加载完成或者滚动到对应区域的时候,我们再加载真实的图片
图片懒加载的目的:
减少页面第一次打开时候,请求资源的次数,让页面加载速度更快(打开页面的速度更快)
开始只加载第一屏幕区域的数据和图片(有的网站是第一屏和第二屏都加载了),剩下区域的内容和图片先不进行加载,当用户滚动到具体的区域的时候在加载,这样也可以为用户节省一些流量(尤其是移动端)
实现图片懒加载步骤:
1.img标签的src不存放图片的地址(如果存放真实的地址,页面一加载图片肯定就加载出来了,我们把真实图片的地址存储在当前img标签的自定义属性上(例如:data-img)
2.为了保证当前图片没有真实地址的时候浏览器中不会出现叉叉或者出现alt中的内容,我们一般都会把图片先隐藏(display:none opacity:0.。。)等后期把真实图片加载出来再让当前图片展示
3.为了看不到真实图片我们最好给一个占位图(要求一定小很小,最好是1kb):我们在img外面包一层div盒子,把占位符赋值给当前盒子的背景图片来处理
=》开始img不显示,显示的是默认的背景图,当img真实地址加载完成后我们让img显示此时真实图片会覆盖住背景图
[图片上传失败...(image-2ba9d9-1571051217181)]
[图片上传失败...(image-5e8387-1571051217181)]
以上实现真实图片加载的方式问题有问题,如果真实内容不存在的地址,我们用上述方式加载原有图片展示了,但是展示的都是叉叉或者alt值
解决方法:真实图片加载的时候先不要操作原始img标签(操作img标签肯定会导致页面中的内容跟着变化或者渲染),我们操作临时创建的标签,当都能正常加载成功我们在操作原始的标签
[图片上传失败...(image-15d3fe-1571051217181)]
解决当图片加载完成后,不在重复执行加载。
[图片上传失败...(image-18eafc-1571051217181)]
同步异步
同步:有先后顺序,一次只做一件事。
异步:异步代码等待时可以同时进行好几件事,相互之间没什么影响。
看到异步,放入程序池队列,满足条件才执行
先执行同步代码,在执行异步的 单线程(只有一个异步代码处理完后才能处理下一个)
定时器,回调函数,ajax请求,所有的事件都是异步操作
多图延迟加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
padding-top: 2000px;
}
div img {
display: block;
width: 300px;
height: 300px;
/*background-size: 25px 25px;*/
}
</style>
</head>
<body>
//如何确定其他屏图片延迟加载,
关键问题:如何确定滚动条滚动到了其他屏图片?
图片的底部到文档的顶部的距离(body上偏移的距离);
多张图片延迟加载:每张图片底部到文档顶部距离都跟卷出去的高度+一屏高度进行比较
滚动条发生移动时
每张图片都得进行如下操作
卷出去的高度+一屏高度>=图片底部到文档顶部的距离
//1.
<div>
<img src="image2/default.gif" alt="" realImg="image2/1.jpg">
<img src="image2/default.gif" alt="" realImg="image2/2.jpg">
<img src=" image2/default.gif" alt="" realImg="image2/3.jpg">
<img src="image2/default.gif" alt="" realImg="image2/4.jpg">
<img src=" image2/default.gif" alt="" realImg="image2/5.jpg">
<img src="image2/default.gif" alt="" realImg="image2/6.jpg">
<img src=" image2/default.gif" alt="" realImg="image2/7.jpg">
<img src="image2/default.gif" alt="" realImg="image2/8.jpg">
<img src=" image2/default.gif" alt="" realImg="image2/9.jpg">
<img src="image2/default.gif" alt="" realImg="image2/10.jpg">
</div>
<script>
function offset(ele) {
var l = ele.offsetLeft;
var t = ele.offsetTop;
var p = ele.offsetParent;
while (p) {
if (navigator.userAgent.indexOf("MSIE 8.0") === -1) {
l += p.clientLeft;
t += p.clientTop;
}
l += p.offsetLeft;
t += p.offsetTop;
p = p.offsetParent;
}
return {
l: l,
t: t
}
}
function win(attr, value) {
//value是否有传值,若没有值表示获取,若有值表示设置
if (typeof value === "undefined") {
return document.documentElement[attr] || document.body[attr];
} else {
if (attr === "scrollTop" || attr === "scrollLeft") {
document.documentElement[attr] = value;
document.body[attr] = value;
}
}
}
var oImgs = document.getElementsByTagName("img");
var clientH = win("clientHeight");//一屏的高度
window.onscroll = function(){//当滚动条发生移动时
//计算卷出去的高度+一屏的高度
for(var i = 0;i<oImgs.length;i++) {
var oImg = oImgs[i];//每张图片
loadImg(oImg);
}
}
function loadImg(oImg){
var scrollT = win("scrollTop");
//求出每张图片底部到文档顶部的距离
var imgT = oImg.offsetHeight+offset(oImg).t;
if(scrollT+clientH>=imgT){
if(oImg.loaded) return;
//把这张图片显示出来
var tempImg = new Image();
tempImg.src = oImg.getAttribute("realImg");
tempImg.onload = function(){//当图片加载成功后才触发
oImg.src = this.src;
oImg.loaded = true;
};
tempImg.onerror = function(){
oImg.src = "image2/error.gif";
}
}
}
</script>
</body>
</html>
网友评论