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数组使用调用方法汇总
Dec 08 Javascript
关于JS判断图片是否加载完成且获取图片宽度的方法
Apr 09 Javascript
使用jquery操作session方法分享
Jan 22 Javascript
JavaScript实现自动消除按钮功能的方法
Aug 05 Javascript
百度多文件异步上传控件webuploader基本用法解析
Nov 07 Javascript
input框中的name和id的区别
Nov 16 Javascript
原生js实现网页顶部自动下拉/收缩广告效果
Jan 20 Javascript
AngularJS基于provider实现全局变量的读取和赋值方法
Jun 28 Javascript
Vue 项目分环境打包的方法示例
Aug 03 Javascript
vue+springboot实现项目的CORS跨域请求
Sep 05 Javascript
用JS实现选项卡
Mar 23 Javascript
JQuery绑定事件四种实现方法解析
Dec 02 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应用提速面面观
2006/10/09 PHP
用PHP制作静态网站的模板框架(三)
2006/10/09 PHP
Ping服务的php实现方法,让网站快速被收录
2012/02/04 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
2016/01/07 PHP
新手常遇到的一些jquery问题整理
2010/08/16 Javascript
jquery 学习之二 属性(类)
2010/11/25 Javascript
Node.js 服务器端应用开发框架 -- Hapi.js
2014/07/29 Javascript
IE6-IE9中tbody的innerHTML不能赋值的解决方法
2014/09/26 Javascript
使用jquery动态加载js文件的方法
2014/12/24 Javascript
javascript批量修改文件编码格式的方法
2015/01/27 Javascript
javascript中的Base64、UTF8编码与解码详解
2015/03/18 Javascript
删除javascript所创建子节点的方法
2015/05/21 Javascript
JavaScript获取URL汇总
2015/06/08 Javascript
JS实现的5级联动Select下拉选择框实例
2015/08/17 Javascript
js动态添加的DIV中的onclick事件简单实例
2016/07/25 Javascript
AngularJS 实现JavaScript 动画效果详解
2016/09/08 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
JavaScript中数组Array.sort()排序方法详解
2017/03/01 Javascript
解决iView中时间控件选择的时间总是少一天的问题
2018/03/15 Javascript
[10:54]Team Spirit vs Navi
2018/06/07 DOTA
[36:13]Mineski vs iG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python实现单线程多任务非阻塞TCP服务端
2017/06/13 Python
python读取文件名并改名字的实例
2019/01/07 Python
对python中的装包与解包实例详解
2019/08/24 Python
通过 Python 和 OpenCV 实现目标数量监控
2020/01/05 Python
CSS3文本换行word-wrap解决英文文本超过固定宽度不换行
2013/10/10 HTML / CSS
html5画布旋转效果示例
2014/01/27 HTML / CSS
伦敦剧院及景点门票:Encore Tickets
2018/07/01 全球购物
英国最大的在线蜡烛商店:Candles Direct
2019/03/26 全球购物
经济管理专业毕业生自荐信范文
2014/01/02 职场文书
反腐倡廉警示教育活动总结
2014/05/05 职场文书
区级文明单位申报材料
2014/05/15 职场文书
2014年化工厂工作总结
2014/11/25 职场文书
2015年党风廉政建设工作总结
2015/04/09 职场文书
大学生安全教育心得体会
2016/01/15 职场文书
mysql sql常用语句大全
2022/06/21 MySQL