背景:
图片是web页面的重要组成部分,也是前端页面优化的重要内容。当用户访问一个比较庞大的页面时,若相关资源没有提前加载,可能会展示给用户一片空白,从而导致用户流失等;再比如受网速的影响,资源加载时间较长,可能使得页面出现错乱等问题。因此预加载就显得很有必要,同时预先加载的页面可以在用户需要时,直接从本地缓存中渲染,减少用户的等待时长。
- 图片优化--------预先加载;
- 提升用户体验效果。
图片预加载分类:
- 无序加载-------例如添加loading页的图片相册、表情包等 ;
- 有序加载-------例如漫画网站的浏览页面等。
实现方案:
原理:通过监听Image对象的onload事件,判断浏览器加载图片的状态。
主要有三个实现步骤:
//1.创建图像对象
var imgObj = new Image();
//2.监听图像的load事件
imgObj.onload = function(){
//执行相应的操作
};
//3.赋值给图片正确的地址
imgObj.src = src;
实现:preLoad插件
//图片预加载
(function($){
function PreLoad(imgs, options){
this.imgs = (typeof imgs === 'string') ? [imgs] : imgs;
this.opts = $.extend({}, PreLoad.DEFAULTS, options);
//判断预加载类型
if(this.opts.order === 'ordered'){
this._ordered();
}else{
this._unordered();
}
}
PreLoad.DEFAULTS = {
order: 'unordered',//默认为无序加载
each: null,//每一张图片加载完毕后执行
all: null//所有图片加载完毕后执行
};
//有序预加载
PreLoad.prototype._ordered = function(){
var imgs = this.imgs,
opts = this.opts
count = 0
len = imgs.length;
load();
//有序预加载
function load(){
var imgObj = new Image();
$(imgObj).on('load error', function(){
opts.each && opts.each(count);
if(count >= len){
//所有图片加载完成
opts.all && opts.all(count);
}else{
//图片未加载完成
load();
}
count++;
});
imgObj.src = imgs[count];
}
}
//无序预加载
PreLoad.prototype._unordered = function(){
var imgs = this.imgs,
opts = this.opts
count = 0
len = imgs.length;
$.each(imgs, function(i, src){
if(typeof src != 'string') return;
// 创建图像对象
var imgObj = new Image();
// 监听图像加载事件
$(imgObj).on('load error', function(){
opts.each && opts.each(count);
if(count >= len - 1){
opts.all && opts.all();
}
count++;
});
// 将正确的图片地址赋值给图像对象
imgObj.src = src;
})
}
// $.fn.extend -> $('#img').preload()
// $.extend -> $.preload()
$.extend({
preLoad: function(imgs, opts){
new PreLoad(imgs, opts);
}
});
})(jQuery);
效果:
1.无序预加载:设置loading页面实现一个图片相册的预加载
<div class="box">
<img src="http://img15.3lian.com/2016/h1/28/49.jpg" alt="pic" id="img" width="800" height="500" />
<p>
<a href="javascript:;" class="btn" data-control="prev">上一页</a>
<a href="javascript:;" class="btn" data-control="next">下一页</a>
</p>
</div>
<!-- 预加载页面 -->
<div class="loading">
<p class="progress">0%</p>
</div>
var imgs = [
'http://img15.3lian.com/2016/h1/28/49.jpg',
'http://www.fonron.com/Ph_mght_2105/eWebEditor/UploadFile/20121116232946760.jpg',
'http://img.jdzj.com/UserDocument/2017z/shanruopeng/Picture/20171013114342422.jpg',
'http://www.baby-edu.com/uploadfile/201412/20141202012322539.jpg'
];
var index = 0,
len = imgs.length
$progress = $('.progress');
//使用预加载插件
$.preLoad(imgs, {
each: function(count){
$progress.html(Math.round((count + 1) / len * 100) + '%');
},
all: function(){
$('.loading').hide();
document.title = '1/' + len;
}
})
由上图可知,无序加载即图片资源在预加载过程中可以同时进行,因为浏览器请求是异步请求。所有图片资源加载完成后,loading页面消失,第一张图片出现,当用户点击下一页按钮时,无序等待,就可以浏览图片。
2.有序预加载:实现漫画网站的浏览模式,即第一张漫画加载完才会加载第二张漫画,直到所以漫画加载完毕。即用户浏览完第一张漫画后,点击下一页按钮,第二张漫画就已经加载好了,这也符合用户的浏览顺序。
<div class="box">
<img src="http://img15.3lian.com/2016/h1/28/49.jpg" alt="pic" id="img" width="800" height="500" />
<p>
<a href="javascript:;" class="btn" data-control="prev">上一页</a>
<a href="javascript:;" class="btn" data-control="next">下一页</a>
</p>
</div>
var imgs = [
'http://img15.3lian.com/2016/h1/28/49.jpg',
'http://www.fonron.com/Ph_mght_2105/eWebEditor/UploadFile/20121116232946760.jpg',
'http://img.jdzj.com/UserDocument/2017z/shanruopeng/Picture/20171013114342422.jpg',
'http://www.baby-edu.com/uploadfile/201412/20141202012322539.jpg'
];
var count = 0,
len = imgs.length,
index = 0;
//使用预加载插件
$.preLoad(imgs, {
order: 'ordered'
});
由上图可知,有序加载即图片资源在预加载过程中按照先后顺序加载完后第一张图片再加载第二张图片,直到加载完所有图片。我们通过函数迭代实现。