js 实现图片预加载(js操作 Image对象属性complete ,事件onload 异步加载图片)


Posted in Javascript onMarch 25, 2011

看个例子:

<input type="button" name="" value="载入图片" onclick="addImg('tt.jpg')" /> 
<script type="text/javascript"> 
<!-- 
function addImg(isrc) 
{ 
var Img = new Image(); 
Img.src = isrc; 
Img.onload = function () 
{ 
document.body.appendChild(Img); 
} 
} 
//--> 
</script>

当包含上述代码的页面打开时并不载入 “tt.jpg” ,当点击按钮时候才载入。当载入完成后触发onload事件显示到页面上。如果你是第一次加载 “tt.jpg" 这张图片的话,运行正常。点击按钮加载并显示一张图片,如果重复点击会怎么样呢?
IE、Opera中,除了第一次加载 图片时候显示正常,之后再点击就没有反应了,刷新也一样。难道它们只触发一次 ”onload“ 事件?是缓存机制?
FF、Chrom中,每点击一次加载一张该图片。

稍微修改下:

<input type="button" name="" value="载入图片" onclick="addImg('tt.jpg')" /> 
<script type="text/javascript"> 
<!-- 
function addImg(isrc) 
{ 
var Img = new Image(); 
Img.onload = function () 
{ 
document.body.appendChild(Img); 
} 
Img.src = isrc; 
} 
//--> 
</script>

运行后发现,奇怪的事情发生了。所有的浏览器都一致了,都是每点击一次加载一张图片。这又是什么原因?由此可以见 IE、Opera 执行过程中并不是只触发一次 onload 事件!

联想一下 Image 对象的一些属性看看,complete、readyState(IE专属值[uninitialized,complete]) (为防止缓存影响效果请更换图片名称!)

<input type="button" name="" value="complete" onclick='alert("complete : "+Img.complete +"\nreadyState : "+Img.readyState)' /> 
<input type="button" name="" value="载入图片" onclick="addImg('mtm.jpg')" /> 
<script type="text/javascript"> 
<!-- 
var Img; 
function addImg(isrc) 
{ 
Img = new Image(); 
//Img.src = isrc; 
Img.onload = function () 
{ 
alert("complete : "+Img.complete +"\nreadyState : "+Img.readyState) 
document.body.appendChild(Img); 
} 
Img.src = isrc; 
} 
//--> 
</script>

经过以上测试,可以看出一些不同点,对于 complete 属性来讲,IE是根据图片是否显示过来判断,就是说当加载的图片显示出来后,complete 属性的值才为 true ,否则一直是 false ,和以前是否加载过该张图片没有关系,即和缓存没有关系!但是其它浏览器表现出来的确不一样,只要以前加载过该图,浏览器有缓存,complete 就为 true ,这和IE的 readyState 属性的表现一致!
至此,可以肯定的是所有的浏览器都会缓存图片!可是上面的问题到底是什么原因导致的呢?
众所周知,从缓存里加载东西的速度是很快的,那么在
...
Img.src = isrc;
Img.onload = ...
...
的过程中,难道 IE、Opera 加载的速度快到,来不及追加事件?

这回加载一张根本不存在的图片看看效果:

<input type="button" name="" value="complete" onclick='alert("complete : "+Imgttmt.complete +"\nreadyState : "+Imgttmt.readyState)' /> 
<input type="button" name="" value="载入图片" onclick="addImg('mtmttyt.jpg')" /> 
<script type="text/javascript"> 
<!-- 
var Imgttmt; 
function addImg(isrc) 
{ 
Imgttmt = new Image(); 
Imgttmt.src = isrc; 
alert("complete : "+Imgttmt.complete +"\nreadyState : "+Imgttmt.readyState) 
Imgttmt.onload = function () 
{ 
alert("impossible") 
} 
} 
//--> 
</script>

可以肯定的是所有浏览器都不触发 onload 事件。从是否缓存或已经加载过图片的角度讲,IE、Opera表现正常,complete 始终为 false ;IE的 readyState 始终为uninitialized 。令人疑惑的是FF,其中 Imgttmt.complete 的值一直是 true ;更令人困惑的是 Chrom,它是在最初 new Imgttmt() 的时候 Imgttmt.complete 值为 false。而之后 Imgttmt.complete 值就一直为 true 了!如果换一张从来没有加载过的图片,FF和Chrom 的行为就一致了,都是一开始加载时, Imgttmt.complete 值为false, 之后为 true!
测试的过程中还发现,脚本的执行顺序的确会影响到类似于 onload 等事件的追加,如果在其显示后在追加事件就没有什么实际意义了!基于 javascript 这种解释性语言的特性,在追加事件的时候一定要注意把事件追加在触发该事件的句柄之前。
Javascript 相关文章推荐
javascript与CSS复习(《精通javascript》)
Jun 29 Javascript
input:checkbox多选框实现单选效果跟radio一样
Jun 16 Javascript
js与jquery实时监听输入框值的oninput与onpropertychange方法
Feb 05 Javascript
微信小程序 时间格式化(util.formatTime(new Date))详解
Nov 16 Javascript
AngularJS Select(选择框)使用详解
Jan 18 Javascript
AugularJS从入门到实践(必看篇)
Jul 10 Javascript
原生JS实现$.param() 函数的方法
Aug 10 Javascript
js删除数组中某几项的方法总结
Jan 16 Javascript
JS实现数组深拷贝的方法分析
Mar 06 Javascript
解决layui的使用以及针对select、radio等表单组件不显示的问题
Sep 05 Javascript
vue.js实现图书管理功能
Sep 24 Javascript
jQuery 实现扁平式小清新导航
Jul 07 jQuery
基于jquery的3d效果实现代码
Mar 23 #Javascript
jquery 操作表格实现代码(多种操作打包)
Mar 20 #Javascript
jQuery实现的Email中的收件人效果(按del键删除)
Mar 20 #Javascript
jquery图片上下tab切换效果
Mar 18 #Javascript
javascript一些实用技巧小结
Mar 18 #Javascript
jquery获取下拉列表的值为null的解决方法
Mar 18 #Javascript
iframe的onload在Chrome/Opera中执行两次Bug的解决方法
Mar 17 #Javascript
You might like
计算一段日期内的周末天数的php代码(星期六,星期日总和)
2009/11/12 PHP
PHP中文件上传的一个问题
2010/09/04 PHP
有关PHP中MVC的开发经验分享
2012/05/17 PHP
php实现读取超大文件的方法
2014/07/28 PHP
php最简单的删除目录与文件实现方法
2014/11/28 PHP
yii 框架实现按天,月,年,自定义时间段统计数据的方法分析
2020/04/04 PHP
js 加载并解析XML字符串的代码
2009/12/13 Javascript
JavaScript中的property和attribute介绍
2011/12/26 Javascript
jquery星级插件、支持页面中多次使用
2012/03/25 Javascript
详解JavaScript的Date对象(制作简易钟表)
2020/04/07 Javascript
Bootstrap每天必学之日期控制
2016/03/07 Javascript
通过隐藏iframe实现无刷新上传文件操作
2016/03/16 Javascript
vue.js初学入门教程(2)
2016/11/07 Javascript
Angular 表单控件示例代码
2017/06/26 Javascript
二维码图片生成器QRCode.js简单介绍
2017/08/18 Javascript
Vue.set()实现数据动态响应的方法
2018/02/07 Javascript
使用Vue.js 和Chart.js制作绚丽多彩的图表
2019/06/15 Javascript
js实现无缝滚动双图切换效果
2019/07/09 Javascript
js实现视图和数据双向绑定的方法分析
2020/02/05 Javascript
JavaScript canvas实现雪花随机动态飘落
2020/02/08 Javascript
浅析Python编写函数装饰器
2016/03/18 Python
python脚本实现xls(xlsx)转成csv
2016/04/10 Python
Python中functools模块函数解析
2017/03/12 Python
Python虚拟环境virtualenv的安装与使用详解
2017/05/28 Python
python发送邮件脚本
2018/05/22 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
python 将dicom图片转换成jpg图片的实例
2020/01/13 Python
Python实现中英文全文搜索的示例
2020/12/04 Python
Python 实现二叉查找树的示例代码
2020/12/21 Python
简单掌握CSS3中resize属性的用法
2016/04/01 HTML / CSS
固特异美国在线轮胎店:Goodyear Tire
2019/02/23 全球购物
GWT都有什么特性
2016/12/02 面试题
2014年店长工作总结
2014/11/17 职场文书
2016年党员读书月活动总结
2016/04/06 职场文书
快速学习Oracle触发器和游标
2021/06/30 Oracle
SQL Server的存储过程与触发器以及系统函数和自定义函数
2022/04/10 SQL Server