再谈javascript图片预加载技术

图片预加载技术的典型应用javascript

如lightbox方式展示照片,无疑须要提早得到大图的尺寸,这样才能居中定位,因为javascript没法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小而后展现出来,因此lightbox显示的图片的速度体验要比直接输出的差不少,而本文说提到的预加载技术主要针对获取图片尺寸。css

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

 

var imgLoad = function (url, callback) {
    var img = new Image();
    img.src = url;
    if (img.complete) {
        callback(img.width, img.height);
    } else {
        img.onload = function () {
            callback(img.width, img.height);
            img.onload = null;
        };
    };
};

 

web应用程序区别于桌面应用程序,响应速度才是最好的用户体验。若是想要速度与优雅兼得,那就必须提早得到图片尺寸,如何在图片没有加载完毕就能获取图片尺寸?java

1、结合flash加载图片,获取图片头部数据的尺寸web

flash虽然很强大,但它与生俱来的缺点让人爱恨交织,加上不少移动设备不支持falsh无疑更是致命的伤,仍是放弃吧。浏览器

2、在服务端保存图片尺寸数缓存

这里不得不提到腾讯Qzone的lightbox相册,它就是这样作的。它能在图片没有加载彻底的时候就居中放大图片,速度与优雅基本兼得。不过它仍然难以免blog插入的外链图片的问题,也只能按传统的方式加载完毕才能展现。app

3、javascript经过占位方式获取图片头部数据的尺ide

十多年的上网经验告诉我:浏览器在加载图片的时候你会看到图片会先占用一块地而后才慢慢加载完毕,而且这里大部分的图片都是没有预设width与height属性的,由于浏览器可以获取图片的头部数据。基于此,只须要使用javascript定时侦测图片的尺寸状态即可得知图片尺寸就绪的状态。测试

实现代码:

 

var imgReady = function (url, callback, error) {
    var width, height, intervalId, check, div,
        img = new Image(),
        body = document.body;
    img.src = url;
    // 从缓存中读取
    if (img.complete) {
        return callback(img.width, img.height);
    };
    // 经过占位提早获取图片头部数据
    if (body) {
        div = document.createElement('div');
        div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;width:1px;
height:1px;overflow:hidden';
        div.appendChild(img)
        body.appendChild(div);
        width = img.offsetWidth;
        height = img.offsetHeight;
        check = function () {
            if (img.offsetWidth !== width || img.offsetHeight !== height) {
                clearInterval(intervalId);
                callback(img.offsetWidth, img.clientHeight);
                img.onload = null;
                div.innerHTML = '';
                div.parentNode.removeChild(div);
            };
        };
        intervalId = setInterval(check, 150);
    };
    // 加载完毕后方式获取
    img.onload = function () {
        callback(img.width, img.height);
        img.onload = img.onerror = null;
        clearInterval(intervalId);
        body && img.parentNode.removeChild(img);
    };
    // 图片加载错误
    img.onerror = function () {
        error && error();
        clearInterval(intervalId);
        body && img.parentNode.removeChild(img);
    };
};

 

好了,请观赏使人愉悦的 DEMO :http://www.planeart.cn/demo/imgReady/

(经过测试的浏览器:Chrome、Firefox、Safari、Opera、IE六、IE七、IE8)

经典论坛交流
http://bbs.blueidea.com/thread-3014603-1-1.html

本文连接:http://www.blueidea.com/tech/web/2011/8335.asp

相关文章
相关标签/搜索