查看: 12092|回复: 0

再谈javascript图片预加载技术

[复制链接]
发表于 2011-3-11 12:44:14 | 显示全部楼层 |阅读模式
台州网址导航
由于javascript无法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小,所以lightbox类效果为了让图片居中显示,导致其速度体验要比直接输出的差很多。而本文所提到的预加载技术主要是让javascript快速获取图片头部数据的尺寸。

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

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;
                };
        };

};highlight:  php可以看到使用onload的方式必须等待图片加载完毕,其速度不敢恭维。

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

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

实现代码:

/*!
* img ready
* http://www.planeart.cn/?p=1121
* TangBin - MIT Licensed
*/

// @param        {String}        图片路径
// @param        {Function}        获取尺寸的回调函数 (参数1接收width;参数2接收height)
// @param        {Function}        加载错误的回调函数 (可选)
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 () {
                        // 如果图像尺寸开始变化,则表示浏览器已经获取了图片头数据并占位
                        // 经过实测只有监听img.offsetWidth才有效,而img.offsetHeight是为了保险
                        if (img.offsetWidth !== width || img.offsetHeight !== height) {
                                clearInterval(intervalId);
                                callback(img.offsetWidth, img.offsetHeight);
                                // 清空img的事件与元素,避免IE内存泄漏
                                img.onload = null;
                                div.innerHTML = '';
                                div.parentNode.removeChild(div);
                        };
                };

                // 定期执行检测
                intervalId = setInterval(check, 150);
        };

        // 等待图片完全加载完毕
        // 这是一个保险操作,如果上面的监听尺寸方法失败则会启用此
        // 如果很小的图像有可能加载时间小于定时器定义的检测间隔时间,则会停止定时器
        img.onload = function () {
                clearInterval(intervalId);
                callback(img.width, img.height);
                img.onload = img.onerror = null;
                body && img.parentNode.removeChild(img);
        };

        // 图像加载错误
        img.onerror = function () {
                error && error();
                clearInterval(intervalId);
                body && img.parentNode.removeChild(img);
        };

};highlight:  php是不是很简单?这样的方式获取摄影级别照片尺寸的速度往往是onload方式的几十多倍,而对于web普通(800×600内)浏览级别的图片能达到秒杀效果。

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

(通过测试的浏览器:Chrome、Firefox、Safari、Opera、IE6、IE7、IE8)
台州维博网络(www.tzweb.com)专门运用PHP+MYSQL/ASP.NET+MSSQL技术开发网站门户平台系统等。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

网站推广
关于我们
  • 台州朗动科技(Tzweb.com)拥有多年开发网站平台系统门户手机客户端等业务的成功经验。主要从事:政企网站,系统平台,微信公众号,各类小程序,手机APP客户端,浙里办微应用,浙政钉微应用、主机域名、虚拟空间、后期维护等服务,满足不同企业公司的需求,是台州地区领先的网络技术服务商!

Hi,扫描关注我

Copyright © 2005-2026 站长论坛 All rights reserved

Powered by 站长论坛 with TZWEB Update Techonolgy Support

快速回复 返回顶部 返回列表