分享

图片预加载的一个简明例子

 CevenCheng 2011-08-03

图片预加载技术的典型应用:如lightbox方式展现照片,无疑需要提前获得大图的尺寸,这样才能居中定位,由于javascript无法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小然后展示出来,所以lightbox显示的图片的速度体验要比直接输出的差很多,而本文说提到的预加载技术主要针对获取图片尺寸。

效果演示

imgReady


 

一段典型的使用预加载获取图片大小的例子:

01var 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应用程序区别于桌面应用程序,响应速度才是最好的用户体验。如果想要速度与优雅兼得,那就必须提前获得图片尺寸,如何在图片没有加载完毕就能获取图片尺寸?

  1. 结合flash加载图片,获取图片头部数据的尺寸?
  2. flash虽然很强大,但它与生俱来的缺点让人爱恨交织,加上很多移动设备不支持falsh无疑更是致命的伤,还是放弃吧。

  3. 在服务端保存图片尺寸数据?
  4. 这里不得不提到腾讯Qzone的lightbox相册,它就是这样做的。它能在图片没有加载完全的时候就居中放大图片,速度与优雅基本兼得。不过它仍然难以避免blog插入的外链图片的问题,也只能按传统的方式加载完毕才能展示。

  5. javascript通过占位方式获取图片头部数据的尺寸?
  6. 十多年的上网经验告诉我:浏览器在加载图片的时候你会看到图片会先占用一块地然后才慢慢加载完毕,并且这里大部分的图片都是没有预设width与height属性的,因为浏览器能够获取图片的头部数据。基于此,只需要使用javascript定时侦测图片的尺寸状态便可得知图片尺寸就绪的状态。

实现代码:

01// imgReady event - 2011.04.02 - TangBin - MIT Licensed
02/**
03* 图片头数据加载就绪事件
04* @see                http://www./?p=1121
05* @param        {String}        图片路径
06* @param        {Function}        尺寸就绪 (参数1接收width; 参数2接收height)
07* @param        {Function}        加载完毕 (可选. 参数1接收width; 参数2接收height)
08* @param        {Function}        加载错误 (可选)
09*/
10var imgReady = (function () {
11        var list = [], intervalId = null,
12 
13        // 用来执行队列
14        tick = function () {
15                var i = 0;
16                for (; i < list.length; i++) {
17                        list[i].end ? list.splice(i--, 1) : list[i]();
18                };
19                !list.length && stop();
20        },
21 
22        // 停止所有定时器队列
23        stop = function () {
24                clearInterval(intervalId);
25                intervalId = null;
26        };
27 
28        return function (url, ready, load, error) {
29                var check, width, height, newWidth, newHeight,
30                        img = new Image();
31 
32                img.src = url;
33 
34                // 如果图片被缓存,则直接返回缓存数据
35                if (img.complete) {
36                        ready(img.width, img.height);
37                        load && load(img.width, img.height);
38                        return;
39                };
40 
41                // 检测图片大小的改变
42                width = img.width;
43                height = img.height;
44                check = function () {
45                        newWidth = img.width;
46                        newHeight = img.height;
47                        if (newWidth !== width || newHeight !== height ||
48                                // 如果图片已经在其他地方加载可使用面积检测
49                                newWidth * newHeight > 1024
50                        ) {
51                                ready(newWidth, newHeight);
52                                check.end = true;
53                        };
54                };
55                check();
56 
57                // 加载错误后的事件
58                img.onerror = function () {
59                        error && error();
60                        check.end = true;
61                        img = img.onload = img.onerror = null;
62                };
63 
64                // 完全加载完毕的事件
65                img.onload = function () {
66                        load && load(img.width, img.height);
67                        !check.end && check();
68                        // IE gif动画会循环执行onload,置空onload即可
69                        img = img.onload = img.onerror = null;
70                };
71 
72                // 加入队列中定期执行
73                if (!check.end) {
74                        list.push(check);
75                        // 无论何时只允许出现一个定时器,减少浏览器性能损耗
76                        if (intervalId === null) intervalId = setInterval(tick, 40);
77                };
78        };
79})();

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多