再谈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 函数式编程的原理
Oct 16 Javascript
javascript 函数声明与函数表达式的区别介绍
Oct 05 Javascript
用jquery写的一个万年历(自写)
Jan 20 Javascript
js实现的全国省市二级联动下拉选择菜单完整实例
Aug 17 Javascript
AngularJS实现给动态生成的元素绑定事件的方法
Dec 14 Javascript
JSON 数据详解及实例代码分析
Jan 20 Javascript
JavaScript中利用构造器函数模拟类的方法
Feb 16 Javascript
Angular 2父子组件数据传递之局部变量获取子组件其他成员
Jul 04 Javascript
浅谈VUE监听窗口变化事件的问题
Feb 24 Javascript
小程序根据手机机型设置自定义底部导航距离
Jun 04 Javascript
小程序click-scroll组件设计
Jun 18 Javascript
微信小程序npm引入vant-weapp的踩坑记录
Aug 01 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
Terran剧情介绍
2020/03/14 星际争霸
php imagecreatetruecolor 创建高清和透明图片代码小结
2010/05/15 PHP
密码框显示提示文字jquery示例
2013/08/29 Javascript
Jquery实现点击按钮,连续地向textarea中添加值的实例代码
2014/03/08 Javascript
javascript中var的重要性分析
2015/02/11 Javascript
JavaScript中的toLocaleDateString()方法使用简介
2015/06/12 Javascript
javascript解析xml实现省市县三级联动的方法
2015/07/25 Javascript
基于jQuery实现的向下滑动二级菜单效果代码
2015/08/31 Javascript
浅谈js中的延迟执行和定时执行
2016/05/31 Javascript
Javascript中this绑定的3种方法与比较
2016/10/13 Javascript
JavaScript 实现 Tab 点击切换实例代码
2017/03/25 Javascript
jQuery简介_动力节点Java学院整理
2017/07/04 jQuery
JS如何设置元素样式的方法示例
2017/08/28 Javascript
微信小程序实现YDUI的ScrollTab组件
2018/02/02 Javascript
在vue项目中引用Iview的方法
2018/09/14 Javascript
JavaScript中的一些实用小技巧总结
2019/04/07 Javascript
Vue组件通信$attrs、$listeners实现原理解析
2020/09/03 Javascript
vue-amap根据地址回显地图并mark的操作
2020/11/03 Javascript
[00:36]DOTA2风云人物相约完美“圣”典 12月17日不见不散
2016/11/30 DOTA
[01:07:19]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第一场
2018/04/06 DOTA
遍历python字典几种方法总结(推荐)
2016/09/11 Python
使用XML库的方式,实现RPC通信的方法(推荐)
2017/06/14 Python
Python温度转换实例分析
2018/01/17 Python
Python装饰器原理与用法分析
2018/04/30 Python
在Python文件中指定Python解释器的方法
2019/02/18 Python
Crucial英睿达法国官网:内存条及SSD固态硬盘升级
2018/07/13 全球购物
德国在线购买葡萄酒网站:Geile Weine
2019/09/24 全球购物
手机促销活动方案
2014/02/05 职场文书
大学生自我评价范文分享
2014/02/21 职场文书
临床医学专业求职信
2014/08/08 职场文书
授权委托书范本(单位)
2014/09/28 职场文书
2014年人民警察入党思想汇报
2014/10/12 职场文书
小学教师2014年度工作总结
2014/12/03 职场文书
企业培训简报范文
2015/07/20 职场文书
Nginx服务器添加Systemd自定义服务过程解析
2021/03/31 Servers
Win11绿屏怎么办?Win11绿屏死机的解决方法
2021/11/21 数码科技