再谈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 相关文章推荐
JQuery Tips(2) 关于$()包装集你不知道的
Dec 14 Javascript
JS 密码强度验证(兼容IE,火狐,谷歌)
Mar 15 Javascript
js RuntimeObject() 获取ie里面自定义函数或者属性的集合
Nov 23 Javascript
JavaScript中常用的六种互动方法示例
Mar 13 Javascript
js右下角弹出提示框示例代码
Jan 12 Javascript
EasyUI加载完Html内容样式渲染完成后显示
Jul 25 Javascript
jQuery根据ID、CLASS、等获取对象的实例
Dec 04 Javascript
微信小程序 特效菜单抽屉效果实例代码
Jan 11 Javascript
JavaScript JSON数据处理全集(小结)
Aug 15 Javascript
React.js组件实现拖拽排序组件功能过程解析
Apr 27 Javascript
JavaScrip如果基于url实现图片下载
Jul 03 Javascript
Vue项目如何引入bootstrap、elementUI、echarts
Nov 26 Vue.js
在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
回首过去10年中最搞笑的10部动漫,哪一部让你节操尽碎?
2020/03/03 日漫
批量获取memcache值并按key的顺序返回的实现代码
2011/06/14 PHP
linux下php上传文件注意事项
2016/06/11 PHP
yii2控制器Controller Ajax操作示例
2016/07/23 PHP
在Laravel中实现使用AJAX动态刷新部分页面
2019/10/15 PHP
关于PHP求解三数之和问题详析
2020/11/09 PHP
再谈javascript 动态添加样式规则 W3C校检
2009/12/25 Javascript
javascript 面向对象 function类
2010/05/13 Javascript
利用jQuery操作对象数组的实现代码
2011/04/27 Javascript
解析prototype,JQuery中跳出each循环的方法
2013/12/12 Javascript
Javascript中的Array数组对象详谈
2014/03/03 Javascript
简介JavaScript中valueOf()方法的使用
2015/06/05 Javascript
jquery自定义右键菜单、全选、不连续选择
2016/03/01 Javascript
Vue.js 和 MVVM 的注意事项
2016/11/07 Javascript
ES6中参数的默认值语法介绍
2017/05/03 Javascript
Vue中的Vux配置指南
2017/12/08 Javascript
webpack项目调试以及独立打包配置文件的方法
2018/02/28 Javascript
Vue.js 使用v-cloak后仍显示变量的解决方法
2018/11/19 Javascript
[01:42]辉夜杯战队访谈宣传片—FANTUAN
2015/12/25 DOTA
[01:03:41]完美世界DOTA2联赛PWL S3 DLG vs Phoenix 第一场 12.17
2020/12/19 DOTA
python数据结构之二叉树的统计与转换实例
2014/04/29 Python
Python的Scrapy爬虫框架简单学习笔记
2016/01/20 Python
python中urllib.unquote乱码的原因与解决方法
2017/04/24 Python
Python类的绑定方法和非绑定方法实例解析
2020/03/04 Python
python numpy实现多次循环读取文件 等间隔过滤数据示例
2020/03/14 Python
利用python 读写csv文件
2020/09/10 Python
jurlique茱莉蔻英国官网:澳洲天然护肤品
2018/08/03 全球购物
营销总经理的岗位职责
2013/12/15 职场文书
听课评语大全
2014/04/30 职场文书
就业协议书样本
2014/08/20 职场文书
世界卫生日宣传活动总结
2015/02/09 职场文书
民事起诉书范本
2015/05/19 职场文书
培养联系人考察意见
2015/06/01 职场文书
信息简报范文
2015/07/21 职场文书
新课程改革心得体会
2016/01/22 职场文书
pytorch 如何把图像数据集进行划分成train,test和val
2021/05/31 Python