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 - HTML的request类
Jul 15 Javascript
基于jQuery实现点击同时更改两个iframe的网址
Jul 01 Javascript
extjs ColumnChart设置不同的颜色实现代码
May 17 Javascript
用原生JS获取CLASS对象(很简单实用)
Oct 15 Javascript
高性能JavaScript DOM编程(1)
Aug 11 Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
Jun 23 Javascript
AngularJS动态菜单操作指令
Apr 25 Javascript
jQuery实现注册会员时密码强度提示信息功能示例
Sep 05 jQuery
JavaScript基于数组实现的栈与队列操作示例
Dec 22 Javascript
vue点击页面空白处实现保存功能
Nov 06 Javascript
基于vue和websocket的多人在线聊天室
Feb 01 Javascript
JavaScript装饰者模式原理与用法实例详解
Mar 09 Javascript
基于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类
2006/07/15 PHP
php有道翻译api调用方法实例
2014/12/22 PHP
ubutu 16.04环境下,PHP与mysql数据库,网页登录验证实例讲解
2017/07/20 PHP
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
js继承call()和apply()方法总结
2014/12/08 Javascript
基于canvas实现的绚丽圆圈效果完整实例
2016/01/26 Javascript
JQuery Ajax WebService传递参数的简单实例
2016/11/02 Javascript
JavaScript原生节点操作小结
2017/01/17 Javascript
基于JavaScript实现下拉列表左右移动代码
2017/02/07 Javascript
Node.js常用工具之util模块
2017/03/09 Javascript
Vue中正确使用jQuery的方法
2017/10/30 jQuery
微信小程序开发之自定义tabBar的实现
2018/09/06 Javascript
webpack实现一个行内样式px转vw的loader示例
2018/09/13 Javascript
微信小程序顶部导航栏滑动tab效果
2019/01/28 Javascript
通过微信公众平台获取公众号文章的方法示例
2019/12/25 Javascript
vue使用axios实现excel文件下载的功能
2020/07/16 Javascript
JavaScript实现世界各地时间显示
2020/09/07 Javascript
收藏整理的一些Python常用方法和技巧
2015/05/18 Python
Python实现分割文件及合并文件的方法
2015/07/10 Python
Python实现SMTP发送邮件详细教程
2021/03/02 Python
Python中如何获取类属性的列表
2016/12/26 Python
Python Json模块中dumps、loads、dump、load函数介绍
2018/05/15 Python
python3.X 抓取火车票信息【修正版】
2018/06/19 Python
pycharm激活码快速激活及使用步骤
2020/03/12 Python
Tensorflow中的降维函数tf.reduce_*使用总结
2020/04/20 Python
如何通过Python实现RabbitMQ延迟队列
2020/11/28 Python
python 邮件检测工具mmpi的使用
2021/01/04 Python
CSMA/CD介质访问控制协议
2015/11/17 面试题
工作的心得体会
2013/12/31 职场文书
三八妇女节标语
2014/10/09 职场文书
学生党员检讨书范文
2014/12/27 职场文书
工作失职检讨书范文
2015/05/05 职场文书
2015年度电厂个人工作总结
2015/05/13 职场文书
初中生物教学随笔
2015/08/15 职场文书
MySQL中你可能忽略的COLLATION实例详解
2021/05/12 MySQL
从零开始在Centos7上部署SpringBoot项目
2022/04/07 Servers