比onload更快获取图片尺寸
文章更新:2011-05-31
lightbox类效果为了让图片居中显示而使用预加载,需要等待完全加载完毕才能显示,体验不佳(如filick相册的全屏效果)。javascript无法获取img文件头数据,真的是这样吗?本文通过一个巧妙的方法让javascript获取它。
这是大部分人使用预加载获取图片大小的例子:
01 |
var imgLoad = function (url, callback) {
|
02 |
var img = new Image();
|
03 |
04 |
img.src = url;
|
05 |
if (img.complete) {
|
06 |
callback(img.width, img.height);
|
07 |
} else {
|
08 |
img.onload = function () {
|
09 |
callback(img.width, img.height);
|
10 |
img.onload = null ;
|
11 |
};
|
12 |
};
|
13 |
14 |
}; |
可以看到上面必须等待图片加载完毕才能获取尺寸,其速度不敢恭维,我们需要改进。
web应用程序区别于桌面应用程序,响应速度才是最好的用户体验。如果想要速度与优雅兼得,那就必须提前获得图片尺寸,如何在图片没有加载完毕就能获取图片尺寸?
十多年的上网经验告诉我:浏览器在加载图片的时候你会看到图片会先占用一块地然后才慢慢加载完毕,并且不需要预设width与height属性,因为浏览器能够获取图片的头部数据。基于此,只需要使用javascript定时侦测图片的尺寸状态便可得知图片尺寸就绪的状态。
当然实际中会有一些兼容陷阱,如width与height检测各个浏览器的不一致,还有webkit new Image()建立的图片会受以处在加载进程中同url图片影响,经过反复测试后的最佳处理方式:
01 |
// 更新: |
02 |
// 05.27: 1、保证回调执行顺序:error > ready > load;2、回调函数this指向img本身 |
03 |
// 04-02: 1、增加图片完全加载后的回调 2、提高性能 |
04 |
05 |
/** |
06 |
* 图片头数据加载就绪事件 - 更快获取图片尺寸
|
07 |
* @version 2011.05.27
|
08 |
* @author TangBin
|
09 |
* @see http://www.planeart.cn/?p=1121
|
10 |
* @param {String} 图片路径
|
11 |
* @param {Function} 尺寸就绪
|
12 |
* @param {Function} 加载完毕 (可选)
|
13 |
* @param {Function} 加载错误 (可选)
|
14 |
* @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
|
15 |
alert('size ready: width=' + this.width + '; height=' + this.height);
|
16 |
});
|
17 |
*/
|
18 |
var imgReady = ( function () {
|
19 |
var list = [], intervalId = null ,
|
20 |
21 |
// 用来执行队列
|
22 |
tick = function () {
|
23 |
var i = 0;
|
24 |
for (; i < list.length; i++) {
|
25 |
list[i].end ? list.splice(i--, 1) : list[i]();
|
26 |
};
|
27 |
!list.length && stop();
|
28 |
},
|
29 |
30 |
// 停止所有定时器队列
|
31 |
stop = function () {
|
32 |
clearInterval(intervalId);
|
33 |
intervalId = null ;
|
34 |
};
|
35 |
36 |
return function (url, ready, load, error) {
|
37 |
var onready, width, height, newWidth, newHeight,
|
38 |
img = new Image();
|
39 |
|
40 |
img.src = url;
|
41 |
42 |
// 如果图片被缓存,则直接返回缓存数据
|
43 |
if (img.complete) {
|
44 |
ready.call(img);
|
45 |
load && load.call(img);
|
46 |
return ;
|
47 |
};
|
48 |
|
49 |
width = img.width;
|
50 |
height = img.height;
|
51 |
|
52 |
// 加载错误后的事件
|
53 |
img.onerror = function () {
|
54 |
error && error.call(img);
|
55 |
onready.end = true ;
|
56 |
img = img.onload = img.onerror = null ;
|
57 |
};
|
58 |
|
59 |
// 图片尺寸就绪
|
60 |
onready = function () {
|
61 |
newWidth = img.width;
|
62 |
newHeight = img.height;
|
63 |
if (newWidth !== width || newHeight !== height ||
|
64 |
// 如果图片已经在其他地方加载可使用面积检测
|
65 |
newWidth * newHeight > 1024
|
66 |
) {
|
67 |
ready.call(img);
|
68 |
onready.end = true ;
|
69 |
};
|
70 |
};
|
71 |
onready();
|
72 |
|
73 |
// 完全加载完毕的事件
|
74 |
img.onload = function () {
|
75 |
// onload在定时器时间差范围内可能比onready快
|
76 |
// 这里进行检查并保证onready优先执行
|
77 |
!onready.end && onready();
|
78 |
|
79 |
load && load.call(img);
|
80 |
|
81 |
// IE gif动画会循环执行onload,置空onload即可
|
82 |
img = img.onload = img.onerror = null ;
|
83 |
};
|
84 |
85 |
// 加入队列中定期执行
|
86 |
if (!onready.end) {
|
87 |
list.push(onready);
|
88 |
// 无论何时只允许出现一个定时器,减少浏览器性能损耗
|
89 |
if (intervalId === null ) intervalId = setInterval(tick, 40);
|
90 |
};
|
91 |
};
|
92 |
})(); |
调用例子:
1 |
imgReady( 'http://www.google.com.hk/intl/zh-CN/images/logo_cn.png' , function () {
|
2 |
alert( 'size ready: width=' + this .width + '; height=' + this .height);
|
3 |
}); |
是不是很简单?这样的方式获取摄影级别照片尺寸的速度往往是onload方式的几十多倍,而对于web普通(800×600内)浏览级别的图片能达到秒杀效果。看了这个再回忆一下你见过的web相册,是否绝大部分都可以重构一下呢?好了,请观赏令人愉悦的 DEMO :
http://www.planeart.cn/demo/imgReady/
(通过测试的浏览器:Chrome、Firefox、Safari、Opera、IE6、IE7、IE8)
相关推荐
而本文所提到的预加载技术主要是让javascript快速获取图片头部数据的尺寸。一段典型的使用预加载获取图片大小的例子: 代码如下: var imgLoad = function (url, callback) { var img = new Image(); img.src = url; ...
JavaScript图片预加载代码,显示loading! 值得下载看看!资源免费,大家分享!! 更多免费资源 http://ynsky.download.csdn.net/
JavaScript图片预加载代码,显示loading.rarJavaScript图片预加载代码,显示loading.rarJavaScript图片预加载代码,显示loading.rarJavaScript图片预加载代码,显示loading.rarJavaScript图片预加载代码,显示...
JS javascript 图片 预加载 实现图片的加载
本文实例为大家分享了javascript实现图片预加载和懒加载的具体代码,供大家参考,具体内容如下 预加载 预加载是预先加载好后面需要用到的资源, 后面使用的时候直接去缓存里取。举个栗子, 比如一个网站的开场动画...
主要介绍了javascript图片预加载实现方法,以完整实例形式分析了JavaScript图片预加载显示的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
当你在页面需要预加载的时候可以使用本页面,还可以在本页面放一些广告或者笑话打发时间的同时给浏览者深刻的影响。
Javascript图片预加载,jquery插件。
主要介绍了Javascript图片预加载,帮助大家理解Javascript图片预加载的实现原理,感兴趣的小伙伴们可以参考一下
图片预加载插件---preload.js
两个小资源,就不分开共享了! 图片预加载,见内容!很小白的,一看就懂。 JS格式化是一个html页面,复制你排版不整齐的代码进去,就可以格式化排版
wxapp-preload 微信小程序图片预加载
个人认为其实最初学习JavaScript最好找到简洁易懂的demo学习,但是往往搜索到一堆的插件,没有一定的js功底看的累,浪费时间,也很难学到什么干货。
实现预加载图片有很多方法,包括使用CSS、JavaScript及两者的各种组合。这些技术可根据不同设计场景设计出相应的解决方案,十分高效。 单纯使用CSS,可容易、高效地预加载图片,代码如下: #preload-01 { backgro
本篇文章介绍了javascript图片懒加载与预加载的分析,详细的介绍了懒加载和预加载的问题,有需要的可以了解一下。
本文实例讲述了javascript图片预加载的方法。分享给大家供大家参考。具体如下: lightbox类效果为了让图片居中显示而使用预加载,需要等待完全加载完毕才能显示,体验不佳(如filick相册的全屏效果)。javascript...