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交互的5种方法
Apr 02 Javascript
javascript的alert box在java中如何显示多行
May 18 Javascript
js获取字符串最后一位方法汇总
Nov 13 Javascript
使用javascript实现雪花飘落的效果
Jan 13 Javascript
js实现类似jquery里animate动画效果的方法
Apr 10 Javascript
Bootstrap表单Form全面解析
Jun 13 Javascript
JavaScript实现时间表动态效果
Jul 15 Javascript
js判断传入时间和当前时间大小实例(超简单)
Jan 11 Javascript
Javascript实现异步编程的过程
Jun 18 Javascript
JavaScript解析及序列化JSON的方法实例分析
Jan 04 Javascript
node.js express框架简介与实现
Jul 23 Javascript
js实现车辆管理系统
Aug 26 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 header示例代码(推荐)
2010/09/08 PHP
PHP中字符与字节的区别及字符串与字节转换示例
2016/10/15 PHP
PHP实现图片压缩
2020/09/09 PHP
Yii2框架配置文件(Application属性)与调试技巧实例分析
2019/05/27 PHP
PHP重载基础知识回顾
2020/09/10 PHP
jQuery的三种$()
2009/12/30 Javascript
Wordpress ThickBox 添加“查看原图”效果代码
2010/12/11 Javascript
使用apply方法处理数组的三个技巧[译]
2012/09/20 Javascript
jquery div拖动效果示例代码
2013/12/08 Javascript
jquery中获得元素尺寸和坐标的方法整理
2014/05/18 Javascript
jquery Validation表单验证使用详解
2020/09/12 Javascript
javascript对象的创建和访问
2016/03/08 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
2016/05/28 Javascript
javaScript中定义类或对象的五种方式总结
2016/12/04 Javascript
webpack打包单页面如何引用的js
2017/06/07 Javascript
inner join 内联与left join 左联的实例代码
2017/09/18 Javascript
详解Vuex管理登录状态
2017/11/13 Javascript
vue-router 实现导航守卫(路由卫士)的实例代码
2018/09/02 Javascript
javascript判断一个变量是数组还是对象
2019/04/10 Javascript
Python实现冒泡,插入,选择排序简单实例
2014/08/18 Python
python传递参数方式小结
2015/04/17 Python
Python实现树莓派WiFi断线自动重连的实例代码
2017/03/16 Python
Python过滤txt文件内重复内容的方法
2018/10/21 Python
python找出因数与质因数的方法
2019/07/25 Python
使用pandas读取表格数据并进行单行数据拼接的详细教程
2021/03/03 Python
印度最大的酒店品牌网络:OYO Rooms
2016/07/24 全球购物
英国最大的电子产品和家电零售企业:Currys PC World
2016/09/24 全球购物
曼城官方网上商店:Manchester City
2019/09/10 全球购物
俄罗斯大型在线书店:Читай-город
2019/10/10 全球购物
国贸专业求职信
2014/06/28 职场文书
在校大学生自我评价范文
2014/09/12 职场文书
初婚初育证明范本
2014/11/24 职场文书
恋恋笔记本观后感
2015/06/16 职场文书
mysql使用instr达到in(字符串)的效果
2022/04/03 MySQL
基于redis+lua进行限流的方法
2022/07/23 Redis
在windows server 2012 r2中安装mysql的详细步骤
2022/07/23 Servers