再谈javascript图片预加载技术(详细演示)


Posted in Javascript onMarch 12, 2011

而本文所提到的预加载技术主要是让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; 
}; 
}; 
};

可以看到使用onload的方式必须等待图片加载完毕,其速度不敢恭维。
web应用程序区别于桌面应用程序,响应速度才是最好的用户体验。如果想要速度与优雅兼得,那就必须提前获得图片尺寸,如何在图片没有加载完毕就能获取图片尺寸?
十多年的上网经验告诉我:浏览器在加载图片的时候你会看到图片会先占用一块地然后才慢慢加载完毕,并且这里大部分的图片都是没有预设width与height属性的,因为浏览器能够获取图片的头部数据。基于此,只需要使用javascript定时侦测图片的尺寸状态便可得知图片尺寸就绪的状态。
实现代码(2011-03-11更新):
2011-03-12 更新:
只使用一定时器,优化性能
/*! 
* img ready v0.3 
* http://www.planeart.cn/?p=1121 
* TangBin - MIT Licensed 
*/ 
// 图片头数据加载就绪事件 
// @param {String} 图片路径 
// @param {Function} 获取尺寸的回调函数 (参数1接收width;参数2接收height) 
// @param {Function} 加载错误的回调函数 (可选) 
(function () { 
var list = [], intervalId = null, 
tick = function () { 
var i = 0; 
for (; i < list.length; i++) { 
list[i].end ? list.splice(i--, 1) : list[i](); 
}; 
!list.length && stop(); 
}, 
stop = function () { 
clearInterval(intervalId); 
intervalId = null; 
}; 
this.imgReady = function (url, callback, error) { 
var check, end, width, height, offsetWidth, offsetHeight, div, 
accuracy = 1024, 
doc = document, 
container = doc.body || doc.getElementsByTagName('head')[0], 
img = new Image(); 
img.src = url; 
if (!callback) return img; 
// 如果图片被缓存,则直接返回缓存数据 
if (img.complete) return callback(img.width, img.height); 
// 向页面插入隐秘图像,用来监听图片是否占位 
div = doc.createElement('div'); 
div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;width:1px;height:1px;overflow:hidden'; 
div.appendChild(img) 
container.appendChild(div); 
width = img.offsetWidth; 
height = img.offsetHeight; 
// 完全加载完毕的事件 
img.onload = function () { 
end(); 
callback(img.width, img.height); 
}; 
// 加载错误后的事件 
img.onerror = function () { 
end(); 
error && error(); 
}; 
// 检测图片是否已经占位 
check = function () { 
offsetWidth = img.offsetWidth; 
offsetHeight = img.offsetHeight; 
if (offsetWidth !== width || offsetHeight !== height || offsetWidth * offsetHeight > accuracy) { 
end(); 
callback(offsetWidth, offsetHeight); 
}; 
}; 
check.url = url; 
// 操作结束后进行清理 
// 删除元素与事件,避免IE内存泄漏 
end = function () { 
check.end = true; 
img.onload = img.onerror = null; 
div.innerHTML = ''; 
div.parentNode.removeChild(div); 
}; 
// 将检测图片是否占位的函数加入定时器列队定期执行 
// 同一图片只加入一个检测器 
// 无论何时只允许出现一个定时器,减少浏览器性能损耗 
!check.end && check(); 
for (var i = 0; i < list.length; i ++) { 
if (list[i].url === url) return; 
}; 
if (!check.end) { 
list.push(check); 
if (!intervalId) intervalId = setInterval(tick, 150); 
}; 
}; 
})();

是不是很简单?这样的方式获取摄影级别照片尺寸的速度往往是onload方式的几十多倍,而对于web普通(800×600内)浏览级别的图片能达到秒杀效果。
好了,请观赏令人愉悦的 DEMO : http://demo.3water.com/js/2011/imgready/
(通过测试的浏览器:Chrome、Firefox、Safari、Opera、IE6、IE7、IE8)
来自:: 唐斌
Javascript 相关文章推荐
javascript编程起步(第二课)
Jan 10 Javascript
jQuery中绑定事件的命名空间详解
Apr 05 Javascript
jquery队列queue与原生模仿其实现方法分享
Mar 25 Javascript
简述JavaScript的正则表达式中test()方法的使用
Jun 16 Javascript
jQuery简单实现页面元素置顶时悬浮效果示例
Aug 01 Javascript
深入理解bootstrap框架之第二章整体架构
Oct 09 Javascript
详解Vue爬坑之vuex初识
Jun 14 Javascript
Angular限制input框输入金额(是小数的话只保留两位小数点)
Jul 13 Javascript
利用node.js实现反向代理的方法详解
Jul 24 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
Feb 07 Javascript
JavaScript中的全局属性与方法深入解析
Jun 14 Javascript
浅谈实现在线预览PDF的几种解决办法
Aug 10 Javascript
在jQuery1.5中使用deferred对象 着放大镜看Promise
Mar 12 #Javascript
使用jquery插件实现图片延迟加载技术详细说明
Mar 12 #Javascript
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
Mar 12 #Javascript
javascript textarea光标定位方法(兼容IE和FF)
Mar 12 #Javascript
JavaScript全局函数使用简单说明
Mar 11 #Javascript
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
Mar 10 #Javascript
始终在屏幕中间显示Div的代码(css+js)
Mar 10 #Javascript
You might like
php建立Ftp连接的方法
2015/03/07 PHP
PHP判断手机是IOS还是Android
2015/12/09 PHP
zend框架实现支持sql server的操作方法
2016/12/08 PHP
php基于PDO实现功能强大的MYSQL封装类实例
2017/02/27 PHP
php-msf源码详解
2017/12/25 PHP
实例讲解php实现多线程
2019/01/27 PHP
laravel 时间格式转时间戳的例子
2019/10/11 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
从javascript语言本身谈项目实战
2006/12/27 Javascript
jQuery 入门讲解1
2009/04/15 Javascript
使用jquery为table动态添加行的实现代码
2011/03/30 Javascript
TreeView 用法(有代码)(asp.net)
2011/07/15 Javascript
解决IE6的PNG透明JS插件使用介绍
2013/04/17 Javascript
基于javascipt-dom编程 table对象的使用
2013/04/22 Javascript
JS Jquery 遍历,筛选页面元素 自动完成(实现代码)
2013/07/08 Javascript
使用javascript控制cookie显示和隐藏背景图
2014/02/12 Javascript
jQuery UI Bootstrap是什么?
2016/06/17 Javascript
使用JavaScript实现在页面中显示距离2017年中秋节的天数
2017/09/26 Javascript
浅谈vue中使用图片懒加载vue-lazyload插件详细指南
2017/10/23 Javascript
微信小程序自定义音乐进度条的实例代码
2018/08/28 Javascript
Python 的内置字符串方法小结
2016/03/15 Python
python实现定时发送qq消息
2019/01/18 Python
用Python+OpenCV对比图像质量的几种方法
2019/07/15 Python
python正则-re的用法详解
2019/07/28 Python
python爬虫解决验证码的思路及示例
2019/08/01 Python
简单了解python装饰器原理及使用方法
2019/12/18 Python
解决Django no such table: django_session的问题
2020/04/07 Python
python使用requests库爬取拉勾网招聘信息的实现
2020/11/20 Python
Notino法国:购买香水和化妆品
2019/04/15 全球购物
德国专业木制品经销商:Holz-Direkt24
2019/12/26 全球购物
《雷雨》教学反思
2014/02/20 职场文书
教师三严三实心得体会
2014/10/11 职场文书
教育合作协议范本
2014/10/17 职场文书
2015年全国“爱牙日”宣传活动总结
2015/03/23 职场文书
nginx常用命令放入shell脚本详解
2021/03/31 Servers
java Nio使用NioSocket客户端与服务端交互实现方式
2021/06/15 Java/Android