预加载的意义及实现方式有:
预加载可以说是牺牲服务器前端性能,换取更好的用户体验,这样可以使用户的操作得到最快的反映。实现预载的方法非常多,可以用CSS(background)、JS(Image)、HTML()都可以。常用的是new Image();,设置其src来实现预载,再使用onload方法回调预载完成事件。只要浏览器把图片下载到本地,同样的src就会使用缓存,这是最基本也是最实用的预载方法。当Image下载完图片头后,会得到宽和高,因此可以在预载前得到图片的大小(方法是用记时器轮循宽高变化)。
怎么样才能实现预加载?
function loadImage(url,callback) {
var img = new Image();
img.src = url;
img.onload = function(){
img.onload = null;
callback.call(img);
}
}
有些浏览器会有兼容性问题,所以可通过img的complete属性判断图片有没加载完成
function loadImage(url,callback) {
var img = new Image();
img.src = url;
if(img.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数
callback.call(img);
return; // 直接返回,不用再处理onload事件
}
img.onload = function(){
img.onload = null;
callback.call(img);
}
}
也就是说如果图片已经在浏览器缓存里面 那么支持直接从浏览器缓存取得直接执行img.complete里面的函数 接着返回.
但是我们可以看到上面的代码:必须等图片加载完成后,可以执行回调函数,也可以说等图片加载后,我们可以获取图片的宽度和高度。那么如果我们想提前获取图片的尺寸那怎么办?上网经验告诉我:浏览器在加载图片的时候你会看到图片会先占用一块地然后才慢慢加载完毕,并且不需要预设width与height属性,因为浏览器能够获取图片的头部数据。基于此,只需要使用javascript定时侦测图片的尺寸状态便可得知图片尺寸就绪的状态。代码如下:
var imgReady = (function(){
var list = [],
intervalId = null;
// 用来执行队列
var queue = function(){
for(var i = 0; i < list.length; i++){
list[i].end ? list.splice(i--,1) : list[i]();
}
!list.length && stop();
};
// 停止所有定时器队列
var stop = function(){
clearInterval(intervalId);
intervalId = null;
}
return function(url, ready, error) {
var onready = {},
width,
height,
newWidth,
newHeight,
img = new Image();
img.src = url;
// 如果图片被缓存,则直接返回缓存数据
if(img.complete) {
ready.call(img);
return;
}
width = img.width;
height = img.height;
// 加载错误后的事件
img.onerror = function () {
error && error.call(img);
onready.end = true;
img = img.onload = img.onerror = null;
};
// 图片尺寸就绪
var onready = function() {
newWidth = img.width;
newHeight = img.height;
if (newWidth !== width || newHeight !== height ||
// 如果图片已经在其他地方加载可使用面积检测
newWidth * newHeight > 1024
) {
ready.call(img);
onready.end = true;
};
};
onready();
// 完全加载完毕的事件
img.onload = function () {
// onload在定时器时间差范围内可能比onready快
// 这里进行检查并保证onready优先执行
!onready.end && onready();
// IE gif动画会循环执行onload,置空onload即可
img = img.onload = img.onerror = null;
};
// 加入队列中定期执行
if (!onready.end) {
list.push(onready);
// 无论何时只允许出现一个定时器,减少浏览器性能损耗
if (intervalId === null) {
intervalId = setInterval(queue, 40);
};
};
}
})();
暂时没有理解这种原理,只能先转载咯。。。。。