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 相关文章推荐
图片自动更新(说明)
Oct 02 Javascript
HTML页面如何象ASP一样接受参数
Feb 07 Javascript
Javascript写了一个清除“logo1_.exe”的杀毒工具(可扫描目录)
Feb 09 Javascript
兼容ie和firefox js关闭代码
Dec 11 Javascript
关于jQuery object and DOM element
Apr 15 Javascript
你必须知道的Javascript知识点之&quot;字面量和对应类型&quot;说明介绍
Apr 23 Javascript
bootstrap和jQuery.Gantt的css冲突 如何解决
May 29 Javascript
ajax级联菜单实现方法实例分析
Nov 28 Javascript
bootstrap表格内容过长时用省略号表示的解决方法
Nov 21 Javascript
JavaScript获取用户所在城市及地理位置
Apr 21 Javascript
javascript拖曳互换div的位置实现示例
Jun 28 Javascript
uniapp 微信小程序 自定义tabBar 导航
Apr 22 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中执行cmd命令的方法
2014/10/11 PHP
php+mysql查询优化简单实例
2015/01/13 PHP
php pdo连接数据库操作示例
2019/11/18 PHP
PHP实现简易图形计算器
2020/08/28 PHP
Javascript绝句欣赏 一些经典的js代码
2012/02/22 Javascript
javascript类型转换示例
2014/04/29 Javascript
javascript实现选中复选框后相关输入框变灰不可用的方法
2015/08/11 Javascript
JavaScript验证Email(3种方法)
2015/09/21 Javascript
RequireJS多页面应用实例分析
2016/06/29 Javascript
Ajax的概述与实现过程
2016/11/18 Javascript
Bootstrap实现带暂停功能的轮播组件(推荐)
2016/11/25 Javascript
探究JavaScript中的五种事件处理程序方式
2016/12/07 Javascript
Angular JS 生成动态二维码的方法
2017/02/23 Javascript
Vue-router 类似Vuex实现组件化开发的示例
2017/09/15 Javascript
vue cli2.0单页面title修改方法
2018/06/07 Javascript
vue如何根据网站路由判断页面主题色详解
2018/11/02 Javascript
基于vue开发微信小程序mpvue-docs跳转页面功能
2019/04/10 Javascript
微信小程序JS加载esmap地图的实例详解
2019/09/04 Javascript
JS实现页面鼠标点击出现图片特效
2020/08/19 Javascript
Python的动态重新封装的教程
2015/04/11 Python
python使用装饰器和线程限制函数执行时间的方法
2015/04/18 Python
Python+tkinter使用80行代码实现一个计算器实例
2018/01/16 Python
从django的中间件直接返回请求的方法
2018/05/30 Python
Python 网络爬虫--关于简单的模拟登录实例讲解
2018/06/01 Python
python去掉 unicode 字符串前面的u方法
2018/10/21 Python
pygame实现雷电游戏雏形开发
2018/11/20 Python
基于python使用tibco ems代码实例
2019/12/20 Python
Python爬虫分析微博热搜关键词的实现代码
2021/02/22 Python
用css3实现当鼠标移进去时当前亮其他变灰效果
2014/04/08 HTML / CSS
HTML5 LocalStorage 本地存储详细概括(多图)
2017/08/18 HTML / CSS
将"引用"作为函数参数有哪些特点
2013/04/05 面试题
《孔子拜师》教学反思
2014/02/24 职场文书
移交协议书
2014/08/19 职场文书
和领导吃饭祝酒词
2015/08/11 职场文书
python元组打包和解包过程详解
2021/08/02 Python
HTML页面中使两个div并排显示的实现
2022/05/15 HTML / CSS