再谈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中实现动画效果的基本操作介绍
Apr 16 Javascript
使用jquery获取网页中图片高度的两种方法
Sep 26 Javascript
jquery实现动态菜单的实例代码
Nov 28 Javascript
jQuery插件datalist实现很好看的input下拉列表
Jul 14 Javascript
jQuery表格插件datatables用法详解
Nov 23 Javascript
layui中layer前端组件实现图片显示功能的方法分析
Oct 13 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
Jan 16 Javascript
纯JS实现的读取excel文件内容功能示例【支持所有浏览器】
Jun 23 Javascript
微信小程序scroll-x失效的完美解决方法
Jul 18 Javascript
JavaScript数据结构与算法之二叉树遍历算法详解【先序、中序、后序】
Feb 21 Javascript
vue实现扫码功能
Jan 17 Javascript
Vue 技巧之控制父类的 slot
Feb 24 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 中文和编码判断代码
2010/05/16 PHP
PHP 八种基本的数据类型小结
2011/06/01 PHP
php简单浏览目录内容的实现代码
2013/06/07 PHP
PHP获取php,mysql,apche的版本信息示例代码
2014/01/16 PHP
PHP启动windows应用程序、执行bat批处理、执行cmd命令的方法(exec、system函数详解)
2014/10/20 PHP
Laravel接收前端ajax传来的数据的实例代码
2017/07/20 PHP
解析js原生方法创建表格效率测试
2013/07/08 Javascript
javascript阻止scroll事件多次执行的思路及实现
2013/11/08 Javascript
jQuery focus和blur事件的应用详解
2014/01/26 Javascript
javascript实现淡蓝色的鼠标拖动选择框实例
2015/05/09 Javascript
jQuery替换节点用法示例(使用replaceWith方法)
2016/09/08 Javascript
jQuery插件zTree实现单独选中根节点中第一个节点示例
2017/03/08 Javascript
vue之数据交互实例代码
2017/06/16 Javascript
详解vue2.0 transition 多个元素嵌套使用过渡
2017/06/19 Javascript
vue在使用ECharts时的异步更新和数据加载详解
2017/11/22 Javascript
Bootstrap实现可折叠分组侧边导航菜单
2018/03/07 Javascript
详解ES6 Symbol 的用途
2018/10/14 Javascript
VUE-cli3使用 svg-sprite-loader
2018/10/20 Javascript
Vue.js中的高级面试题及答案
2020/01/13 Javascript
antd design table更改某行数据的样式操作
2020/10/31 Javascript
Eclipse + Python 的安装与配置流程
2013/03/05 Python
在Python中用has_key()方法查找键是否存在的教程
2015/05/21 Python
python实现数组插入新元素的方法
2015/05/22 Python
pandas按行按列遍历Dataframe的几种方式
2019/10/23 Python
Pycharm中import torch报错的快速解决方法
2020/03/05 Python
python保留格式汇总各部门excel内容的实现思路
2020/06/01 Python
使用python批量修改XML文件中图像的depth值
2020/07/22 Python
Python爬虫之App爬虫视频下载的实现
2020/12/08 Python
详解纯CSS3制作的20种loading动效
2017/07/05 HTML / CSS
CSS3实现的文本3D效果附图
2014/09/03 HTML / CSS
专科毕业生求职简历的自我评价
2013/10/12 职场文书
文秘个人求职信范文
2014/04/22 职场文书
质量保证书范本
2014/04/29 职场文书
银行求职信范文怎么写
2015/03/20 职场文书
《秋思》教学反思
2016/02/23 职场文书
因个人工作失误检讨书
2019/06/21 职场文书