占位图(兜底图):
真实图片太大还没有加载完之前先用一张占位图表示这个位置将来会有图片或者说明这个位置是有图片的但是不知道什么原因真正的图片没有加载出来用户只能看到这张占位图;
什么是图片懒加载:
懒加载也就是延迟加载,当访问一个页面的时候,先把img元素渲染出来,但是不给它真正的src地址,只有当用户需要看到真正图片的时候,才设置图片正真的路径,让图片显示出来。
为什么要使用懒加载:
在一个页面中,假设有20张图片,每张为100kb,用户在不点滚动条的时候看到的只有4张,如果这20张图片都设置了真正的src,那么当页面首次加载的时候浏览器会立即请求这20张图片资源,需要2000kb的流量;
但是我们做懒加载只请求用户看到的4张图片的话,浏览器只请求这4张图片资源,需要的流量只有400kb。这种手段可以大大减少首屏时间。
懒加载的实现步骤:
1)首先,不要将真正的图片地址放到src属性中,此时放到src中的是一张兜底图,而是放到其它属性(picAddress)中。
2)页面加载完成后,根据scrollTop判断图片是否在用户的视野内,如果在,则将picAddress属性中的值取出存放到src属性中。
3)在滚动事件中重复判断图片是否进入视野,如果进入,则将picAddress属性中的值取出存放到src属性中。
案例:
index.html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<style>
body{
text-align: center;
}
.game-detail-logo{
width: 750px;
height: 430px;
text-align: center;
margin-top:30px;
}
</style>
<img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4003935283,4035293154&fm=27&gp=0.jpg">
<img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1535003204948&di=7f297fc3bd01dcbca58f47c470ae9b9e&imgtype=0&src=http%3A%2F%2Fpic50.nipic.com%2Ffile%2F20141019%2F19104397_104929568000_2.jpg">
<img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="http://i1.hdslb.com/bfs/archive/062705867631af9f8e83aadf6d8a1f935b25cbc2.jpg">
<img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2390937513,1169699994&fm=27&gp=0.jpg">
<img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6169699994&fm=27&gp=0.jpg">
<img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3947968217,2342505746&fm=27&gp=0.jpg">
</body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript" src="lazyLoadImg.js"></script>
</html>
lazyLoadImg.js
/*
* @example
* <img src="" class="lazyLoadImg" picAddress="">
* @param src里面写的是占位图或者说兜底图地址(一张默认填充图)
* @param class="lazyLoadImg" 是必须的标识
* @param picAddress里面写的是真正需要懒加载的图片地址
*/
const lazyLoadImg = {
initConfig() {
const self = this;
self.imgObject.srcFlag = 'picAddress'; // 图片地址
self.imgObject.class = 'lazyLoadImg'; // 惰性加载的图片需要添加的class
self.imgObject.sensitivity = 40; // 鼠标滚动敏感度,该值越小,惰性越强(加载越少)
self.imgObject.init();
},
imgObject: {
trigger() {
const self = this;
const eventType = (self.isPhone && 'touchend') || 'scroll';
self.imgListData = $('img.' + self.class + '');
$(window).trigger(eventType);
},
init() {
var self = this;
$(window).on('scroll', function() {
self.isLoadImg();
});
self.trigger();
},
isLoadImg() {
const self = this;
function loadNeedImg(img) { // 判断哪些img元素需要加载
const windowPageYOffset = window.pageYOffset; // 滚动条距离窗口顶部的偏移量
const offsetAddInner = window.pageYOffset + window.innerHeight; // window.innerHeight返回窗口的文档显示区的高度
const imgOffsetTop = img.offset().top; // 当前img元素距离窗口顶部的偏移量
return (
imgOffsetTop >= windowPageYOffset && // 确保img元素在窗口内
imgOffsetTop - self.sensitivity <= offsetAddInner //当前img元素是不是在窗口可见范围内,不可见返回:false
);
}
function loadImg(img, index) {
const imgUrl = img.attr(self.srcFlag);
const imgLazy = img.attr('src');
img.attr('src', imgUrl);
img[0].onload || // 开始向服务器请求加载图片
((img[0].onload = function() {
$(this)
.removeClass(self.class)
.removeAttr(self.srcFlag),
(self.imgListData[index] = null),
(this.onerror = this.onload = null);
}),
(img[0].onerror = function() {
(this.src = imgLazy),
$(this)
.removeClass(self.class)
.removeAttr(self.srcFlag),
(self.imgListData[index] = null),
(this.onerror = this.onload = null);
}));
}
self.imgListData.each(function(index, val) {
if (!val) return;
const img = $(val);
if (!loadNeedImg(img)) return;
const aa = img.attr(self.srcFlag);
if (!img.attr(self.srcFlag)) return;// 判断是否有规定的picAddress属性,没有则退出当次循环
loadImg(img, index);
});
},
},
};
lazyLoadImg.initConfig();
案例运行注意点:
1)将浏览器变成手机调试模式,Chrome最佳
2)手机模式后高度不能太高(越矮越好),需要出现滚动条,以便滚动下去测试后面的图片
3)网络限速将online设成mid-tier mobile或者low-end mobile更容易看到效果
案例效果:
首次运行时,会先出现占位图(兜底图),然后加载其他图片;当滚动到后面的图片时再按需请求对应的图片资源