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 相关文章推荐
jQuery 操作下拉列表框实现代码
Feb 22 Javascript
Javascript动态绑定事件的简单实现代码
Dec 25 Javascript
jQuery右键菜单contextMenu使用实例
Sep 28 Javascript
div模拟选择框示例代码
Nov 03 Javascript
javascript得到当前页的来路即前一页地址的方法
Feb 18 Javascript
Js实现动态添加删除Table行示例
Apr 14 Javascript
jQuery实现响应浏览器缩放大小并改变背景颜色
Oct 31 Javascript
纯JavaScript代码实现移动设备绘图解锁
Oct 16 Javascript
JavaScript的this关键字的理解
Jun 18 Javascript
移动前端图片压缩上传的实例
Dec 06 Javascript
Thinkjs3新手入门之如何使用静态资源目录
Dec 06 Javascript
小程序如何获取多个formId实现详解
Sep 20 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强制图片下载的方法
2015/03/24 PHP
php判断str字符串是否是xml格式数据的方法示例
2017/07/26 PHP
PHP cookie与session会话基本用法实例分析
2019/11/18 PHP
PHP 超级全局变量相关总结
2020/06/30 PHP
Javascript - HTML的request类
2006/07/15 Javascript
Javascript 八进制转义字符(8进制)
2011/04/08 Javascript
E3 tree 1.6在Firefox下显示问题的修复方法
2013/01/30 Javascript
JQuery打造省市下拉框联动效果
2014/05/18 Javascript
nodejs命令行参数处理模块commander使用实例
2014/09/17 NodeJs
使用Sticker.js实现贴纸效果
2015/01/28 Javascript
Nodejs学习笔记之入门篇
2015/04/16 NodeJs
JavaScript的RequireJS库入门指南
2015/07/01 Javascript
超简单的Vue.js环境搭建教程
2017/03/17 Javascript
AngularJS1.X学习笔记2-数据绑定详解
2017/04/01 Javascript
详解Angular路由之路由守卫
2018/05/10 Javascript
JS实现的文件拖拽上传功能示例
2018/05/21 Javascript
在小程序中使用腾讯视频插件播放教程视频的方法
2018/07/10 Javascript
vue项目打包部署_nginx代理访问方法详解
2018/09/20 Javascript
vue-cli+axios实现文件上传下载功能(下载接收后台返回文件流)
2019/05/10 Javascript
图解NodeJS实现登录注册功能
2019/09/16 NodeJs
JS面向对象实现飞机大战
2020/08/26 Javascript
vue实现表格合并功能
2020/12/01 Vue.js
[06:44]2018DOTA2亚洲邀请赛4.5 SOLO赛 MidOne vs Sumail
2018/04/06 DOTA
Python程序设计入门(5)类的使用简介
2014/06/16 Python
Python中xrange与yield的用法实例分析
2017/12/26 Python
Python随机函数random()使用方法小结
2018/04/29 Python
python 读写文件,按行修改文件的方法
2018/07/12 Python
Python 使用Numpy对矩阵进行转置的方法
2019/01/28 Python
利用python计算时间差(返回天数)
2019/09/07 Python
Python调用飞书发送消息的示例
2020/11/10 Python
Clarins娇韵诗英国官网:来自法国的天然护肤品牌
2017/04/18 全球购物
学生会竞选演讲稿
2014/04/24 职场文书
酒店端午节活动方案
2014/08/26 职场文书
幼师中班个人总结
2015/02/12 职场文书
聊聊golang中多个defer的执行顺序
2021/05/08 Golang
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电