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
* @see http://blog.phpdr.net/js-get-image-size.html
09
* @param {String} 图片路径
10
* @param {Function} 尺寸就绪
11
* @param {Function} 加载完毕 (可选)
12
* @param {Function} 加载错误 (可选)
13
* @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
14
alert('size ready: width=' + this.width + '; height=' + this.height);
15
});
16
*/
17
var
imgReady = (
function
() {
18
var
list = [], intervalId =
null
,
19
20
// 用来执行队列
21
tick =
function
() {
22
var
i = 0;
23
for
(; i < list.length; i++) {
24
list[i].end ? list.splice(i--, 1) : list[i]();
25
};
26
!list.length && stop();
27
},
28
29
// 停止所有定时器队列
30
stop =
function
() {
31
clearInterval(intervalId);
32
intervalId =
null
;
33
};
34
35
return
function
(url, ready, load, error) {
36
var
onready, width, height, newWidth, newHeight,
37
img =
new
Image();
38
39
img.src = url;
40
41
// 如果图片被缓存,则直接返回缓存数据
42
if
(img.complete) {
43
ready.call(img);
44
load && load.call(img);
45
return
;
46
};
47
48
width = img.width;
49
height = img.height;
50
51
// 加载错误后的事件
52
img.onerror =
function
() {
53
error && error.call(img);
54
onready.end =
true
;
55
img = img.onload = img.onerror =
null
;
56
};
57
58
// 图片尺寸就绪
59
onready =
function
() {
60
newWidth = img.width;
61
newHeight = img.height;
62
if
(newWidth !== width || newHeight !== height ||
63
// 如果图片已经在其他地方加载可使用面积检测
64
newWidth * newHeight > 1024
65
) {
66
ready.call(img);
67
onready.end =
true
;
68
};
69
};
70
onready();
71
72
// 完全加载完毕的事件
73
img.onload =
function
() {
74
// onload在定时器时间差范围内可能比onready快
75
// 这里进行检查并保证onready优先执行
76
!onready.end && onready();
77
78
load && load.call(img);
79
80
// IE gif动画会循环执行onload,置空onload即可
81
img = img.onload = img.onerror =