JavaScript与Image加载事件(onload)、加载状态(complete)


Posted in Javascript onFebruary 14, 2011

昨天用jQuery插件aeImageResize,发现它更有优势:每张图片加载完后,会马上进行等比缩放。
这归于图片对象Image的加载事件onload的功劳。
查看插件的源码,发现它也依赖图片对象的complete属性和onload事件,并且特别把IE6区分对待,到底IE6在图片加载对象上,与其它浏览器有什么不同呢?

看下文:

通过js操纵DOM很多情况下都是为了实现和当前页html元素的异步载入,我谈谈对Image对象的一些认识。
看个例子:

<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 &amp; DHTML 实例编程(教程)基础知识
Jun 02 Javascript
jquery 新浪网易的评论块制作
Jul 01 Javascript
腾讯与新浪的通过IP地址获取当前地理位置(省份)的接口
Jul 26 Javascript
js转化毫秒为时间格式代码
Apr 10 Javascript
Iframe实现跨浏览器自适应高度解决方法
Sep 02 Javascript
将JavaScript的jQuery库中表单转化为JSON对象的方法
Nov 17 Javascript
indexedDB bootstrap angularjs之 MVC DOMO (应用示例)
Jun 20 Javascript
JavaScript实现图像模糊化的方法实例
Jan 15 Javascript
JavaScript中数组常见操作技巧
Sep 01 Javascript
javaScript日期工具类DateUtils详解
Dec 08 Javascript
详解Angular5 路由传参的3种方法
Apr 28 Javascript
Vue 解决父组件跳转子路由后当前导航active样式消失问题
Jul 21 Javascript
JQuery 选择器、过滤器介绍
Feb 14 #Javascript
AJAX分页的代码(后台asp.net)
Feb 14 #Javascript
基于jquery的图片的切换(以数字的形式)
Feb 14 #Javascript
jquery isType() 类型判断代码
Feb 14 #Javascript
jquery isEmptyObject判断是否为空对象的函数
Feb 14 #Javascript
jquery each()源代码
Feb 14 #Javascript
jquery trim() 功能源代码
Feb 14 #Javascript
You might like
ThinkPHP CURD方法之order方法详解
2014/06/18 PHP
php时间戳格式化显示友好的时间函数分享
2014/10/21 PHP
php中二分法查找算法实例分析
2016/09/22 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
2019/12/18 PHP
Cookie 小记
2010/04/01 Javascript
js如何设置在iframe框架中指定div不显示
2013/12/04 Javascript
JS脚本defer的作用示例介绍
2014/01/02 Javascript
使用jquery中height()方法获取各种高度大全
2014/04/02 Javascript
javascript中的return和闭包函数浅析
2014/06/06 Javascript
jQueryMobile之Helloworld与页面切换的方法
2015/02/04 Javascript
让Vue也可以使用Redux的方法
2018/05/23 Javascript
vue使用一些外部插件及样式的配置代码
2019/11/18 Javascript
vue-cli设置css不生效的解决方法
2020/02/07 Javascript
[47:35]VP vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/20 DOTA
Flask的图形化管理界面搭建框架Flask-Admin的使用教程
2016/06/13 Python
Django中数据库的数据关系:一对一,一对多,多对多
2018/10/21 Python
使用python接入微信聊天机器人
2020/03/31 Python
详解python中的index函数用法
2019/08/06 Python
python 数据生成excel导出(xlwt,wlsxwrite)代码实例
2019/08/23 Python
Python实现Restful API的例子
2019/08/31 Python
nginx+uwsgi+django环境搭建的方法步骤
2019/11/25 Python
使用tqdm显示Python代码执行进度功能
2019/12/08 Python
python使用rsa非对称加密过程解析
2019/12/28 Python
安装完Python包然后找不到模块的解决步骤
2020/02/13 Python
python如何提取英语pdf内容并翻译
2020/03/03 Python
Python中猜拳游戏与猜筛子游戏的实现方法
2020/09/04 Python
CSS3 Calc实现滚动条出现页面不跳动问题
2017/09/14 HTML / CSS
悦木之源美国官网:Origins美国
2016/08/01 全球购物
英国最大的奢侈珠宝和手表网站:C W Sellors
2017/02/10 全球购物
幼儿园爱国卫生月活动总结
2014/06/30 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
党的群众路线教育实践活动批评与自我批评发言稿
2014/10/16 职场文书
2015年助理政工师工作总结
2015/05/26 职场文书
Go语言中的UTF-8实现
2021/04/26 Golang
使用CSS实现小三角边框原理解析
2021/11/07 HTML / CSS
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python