再谈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 输入框内容格式验证代码
Feb 11 Javascript
javascript getElementsByClassName实现代码
Oct 11 Javascript
Jquery异步提交表单代码分享
Mar 26 Javascript
微信公众号 客服接口的开发实例详解
Sep 28 Javascript
JavaScript 数组的深度复制解析
Nov 02 Javascript
JS实现的表头列头固定页面功能示例
Jan 10 Javascript
easyui 中的datagrid跨页勾选问题的实现方法
Jan 18 Javascript
使用jQuery ajaxupload插件实现无刷新上传文件
Apr 23 jQuery
浅谈使用React.setState需要注意的三点
Dec 18 Javascript
360doc网站不登录就无法复制内容的解决方法
Jan 27 Javascript
手写Node静态资源服务器的实现方法
Mar 20 Javascript
JS实现的倒计时恢复按钮点击功能【可用于协议阅读倒计时】
Apr 19 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
thinkPHP下ueditor的使用方法详解
2015/12/26 PHP
YII2框架中使用yii.js实现的post请求
2017/04/09 PHP
FireFox JavaScript全局Event对象
2009/06/14 Javascript
IE8 中使用加速器(Activities)
2010/05/14 Javascript
在javascript中如何得到中英文混合字符串的长度
2014/01/17 Javascript
js格式化时间小结
2014/11/03 Javascript
JavaScrip调试技巧之断点调试
2015/10/22 Javascript
Angular.JS中指令ng-if的注意事项小结
2017/06/21 Javascript
高性能的javascript之加载顺序与执行原理篇
2018/01/14 Javascript
Javascript格式化并高亮xml字符串的方法及注意事项
2018/08/13 Javascript
JavaScript实现简单计算器功能
2019/12/19 Javascript
JS数组方法concat()用法实例分析
2020/01/18 Javascript
详细介绍解决vue和jsp结合的方法
2020/02/06 Javascript
JS script脚本中async和defer区别详解
2020/06/24 Javascript
[01:21]辉夜杯战队访谈宣传片—CDEC
2015/12/25 DOTA
[02:03]《现实生活中的DOTA2》—林书豪&DOTA2职业选手出演短片
2015/08/18 DOTA
Python运算符重载详解及实例代码
2017/03/07 Python
Python 从相对路径下import的方法
2018/12/04 Python
python 产生token及token验证的方法
2018/12/26 Python
Pytorch之view及view_as使用详解
2019/12/31 Python
Tkinter中复选菜单是否被选中的判断与设置方式
2020/03/04 Python
详解Python爬虫爬取博客园问题列表所有的问题
2021/01/18 Python
英国简约舒适女装品牌:Great Plains
2018/07/27 全球购物
linux面试题参考答案(8)
2016/04/19 面试题
CNC数控操作工岗位职责
2013/11/19 职场文书
大学校庆邀请函
2014/01/11 职场文书
消防安全检查制度
2014/02/04 职场文书
教师求职自荐信
2014/03/09 职场文书
会计专业个人自我鉴定
2014/03/21 职场文书
党的群众路线对照检查材料范文
2014/09/24 职场文书
2015年幼儿园德育工作总结
2015/05/25 职场文书
2015年庆祝国庆节66周年演讲稿
2015/07/30 职场文书
中秋节感想
2015/08/10 职场文书
小学四年级作文之人物作文
2019/11/06 职场文书
springboot中一些比较常用的注解总结
2021/06/11 Java/Android
深入理解python协程
2021/06/15 Python