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 相关文章推荐
首页图片漂浮效果示例代码
Jun 05 Javascript
JS实现在页面随时自定义背景颜色的方法
Feb 27 Javascript
鼠标经过子元素触发mouseout,mouseover事件的解决方案
Jul 26 Javascript
JS弹出新窗口被拦截的解决方法
Aug 09 Javascript
JavaScript实现时钟滴答声效果
Jan 29 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
Feb 05 Javascript
vue组件实现文字居中对齐的方法
Aug 23 Javascript
在vue中使用jointjs的方法
Mar 24 Javascript
vue动画之点击按钮往上渐渐显示出来的实例
Sep 29 Javascript
简单实现vue中的依赖收集与响应的方法
Feb 18 Javascript
简单了解vue.js数组的常用操作
Jun 17 Javascript
JS遍历树层级关系实现原理解析
Aug 31 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数字游戏 计算24算法
2012/06/10 PHP
自己在做项目过程中学到的PHP知识收集
2012/08/20 PHP
Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法
2016/03/29 PHP
关于Laravel Route重定向的一个注意点
2017/01/16 PHP
javascript Split方法,indexOf方法、lastIndexOf 方法和substring 方法
2009/03/21 Javascript
JQuery 初体验(建议学习jquery)
2009/04/25 Javascript
jQuery之日期选择器的深入解析
2013/06/19 Javascript
js控制input框只读实现示例
2014/01/20 Javascript
angularjs指令中的compile与link函数详解
2014/12/06 Javascript
jQuery实现背景弹性滚动的导航效果
2016/06/01 Javascript
jQuery设置聚焦并使光标位置在文字最后的实现方法
2016/08/02 Javascript
Js获取当前日期时间及格式化代码
2016/09/17 Javascript
简单理解vue中Props属性
2016/10/27 Javascript
详谈jQuery.load()和Jsp的include的区别
2017/04/12 jQuery
Thinkphp5微信小程序获取用户信息接口的实例详解
2017/09/26 Javascript
详解vue-cli项目中怎么使用mock数据
2018/05/29 Javascript
Angularjs实现多图片上传预览功能
2018/07/18 Javascript
在移动端使用vue-router和keep-alive的方法示例
2018/12/02 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
js实现简单贪吃蛇游戏
2020/05/15 Javascript
对python_discover方法遍历所有执行的用例详解
2019/02/13 Python
详解将Pandas中的DataFrame类型转换成Numpy中array类型的三种方法
2019/07/06 Python
基于python判断目录或者文件代码实例
2019/11/29 Python
python 3.8.3 安装配置图文教程
2020/05/21 Python
DRF框架API版本管理实现方法解析
2020/08/21 Python
美国一家专业的太阳镜网上零售商:Solstice太阳镜
2016/07/25 全球购物
Pandora德国官网:购买潘多拉手链、戒指、项链和耳环
2020/02/20 全球购物
Web Service面试题:如何搭建Axis2的开发环境
2012/06/20 面试题
高分子材料与工程专业个人求职信
2013/12/15 职场文书
联欢晚会主持词
2014/03/25 职场文书
元旦联欢会策划方案
2014/06/11 职场文书
2014年人事专员工作总结
2014/11/19 职场文书
初中信息技术教学计划
2015/01/22 职场文书
2015年大班保育员工作总结
2015/05/18 职场文书
公司联欢会主持词
2015/07/04 职场文书
周一早安温馨问候祝福语!
2019/07/15 职场文书