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模块模式分析
May 16 Javascript
js精度溢出解决方案
Dec 02 Javascript
Jquery多选下拉列表插件jquery multiselect功能介绍及使用
May 24 Javascript
JavaScript变量的作用域全解析
Aug 14 Javascript
IE7浏览器窗口大小改变事件执行多次bug及IE6/IE7/IE8下resize问题
Aug 21 Javascript
cocos2dx骨骼动画Armature源码剖析(三)
Sep 08 Javascript
Javascript实现检测客户端类型代码封包
Dec 03 Javascript
微信小程序 网络请求(GET请求)详解
Nov 16 Javascript
javascript基于原型链的继承及call和apply函数用法分析
Dec 15 Javascript
浅谈PDF.js使用心得
Jun 07 Javascript
深入学习JavaScript中的bom
May 27 Javascript
jQuery表单校验插件validator使用方法详解
Feb 18 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函数,php爱好者站推荐
2007/03/19 PHP
php通过淘宝API查询IP地址归属等信息
2015/12/25 PHP
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
2020/04/14 PHP
javascript 短路法代码精简
2009/08/20 Javascript
js播放wav文件(源码)
2013/04/22 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
jquery插件bxslider用法实例分析
2015/04/16 Javascript
学习JavaScript设计模式之中介者模式
2016/01/14 Javascript
详解JavaScript正则表达式之分组匹配及反向引用
2016/03/09 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
2016/08/24 Javascript
学好js,这些js函数概念一定要知道【推荐】
2017/01/19 Javascript
webpack配置打包后图片路径出错的解决
2018/04/26 Javascript
vue中子组件的methods中获取到props中的值方法
2018/08/27 Javascript
JavaScript代码实现微博批量取消关注功能
2021/02/05 Javascript
[06:24]DOTA2亚洲邀请赛小组赛第三日 TOP10精彩集锦
2015/02/01 DOTA
Python写的PHPMyAdmin暴力破解工具代码
2014/08/06 Python
python使用PIL缩放网络图片并保存的方法
2015/04/24 Python
python+django快速实现文件上传
2016/10/24 Python
windows下python之mysqldb模块安装方法
2017/09/07 Python
Python通过Pygame绘制移动的矩形实例代码
2018/01/03 Python
python实现黑客字幕雨效果
2018/06/21 Python
python识别验证码图片实例详解
2020/02/17 Python
Keras框架中的epoch、bacth、batch size、iteration使用介绍
2020/06/10 Python
零基础学Python之前需要学c语言吗
2020/07/21 Python
解决python便携版无法直接运行py文件的问题
2020/09/01 Python
HTML5仿微信聊天界面、微信朋友圈实例代码
2018/01/29 HTML / CSS
将一个文本文件的内容按倒序打印出来
2015/01/05 面试题
某公司面试题
2012/03/05 面试题
手机银行营销方案
2014/03/14 职场文书
大学生职业生涯规划书汇总
2014/03/20 职场文书
学生社团文化节开幕式主持词
2014/03/28 职场文书
欢迎领导标语
2014/06/27 职场文书
男性健康日的活动方案
2014/08/18 职场文书
新闻发布会活动策划方案
2014/09/15 职场文书
追悼会家属答谢词
2015/09/29 职场文书
vue基于Teleport实现Modal组件
2021/05/31 Vue.js