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 相关文章推荐
bcastr2.0 通用的图片浏览器
Nov 22 Javascript
再谈javascript图片预加载技术(详细演示)
Mar 12 Javascript
Javascript根据指定下标或对象删除数组元素
Dec 21 Javascript
黑帽seo劫持程序,js劫持搜索引擎代码
Sep 15 Javascript
jquery树形菜单效果的简单实例
Jun 06 Javascript
jQuery实现点击查看大图并以弹框的形式居中
Aug 08 Javascript
vue开发心得和技巧分享
Oct 27 Javascript
JavaScript中this的用法及this在不同应用场景的作用解析
Apr 13 Javascript
Angular.js初始化之ng-app的自动绑定与手动绑定详解
Jul 31 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
May 27 Javascript
微信小程序自定义弹窗实现详解(可通用)
Jul 04 Javascript
jQuery HTML获取内容和属性操作实例分析
May 20 jQuery
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
Godaddy空间Zend Optimizer升级方法
2010/05/10 PHP
解析php curl_setopt 函数的相关应用及介绍
2013/06/17 PHP
解析wamp5下虚拟机配置文档
2013/06/27 PHP
浅谈PHP错误类型及屏蔽方法
2017/05/27 PHP
jquery实现漂浮在网页右侧的qq在线客服插件示例
2013/05/13 Javascript
JS 精确统计网站访问量的实例代码
2013/07/05 Javascript
node.js中的socket.io的广播消息
2014/12/15 Javascript
jQuery实现的类似淘宝网站搜索框样式代码分享
2015/08/24 Javascript
jQuery获取DOM节点实例分析(2种方式)
2015/12/15 Javascript
你知道setTimeout是如何运行的吗?
2016/08/16 Javascript
js实时获取窗口大小变化的实例代码
2016/11/18 Javascript
jQuery 判断元素整理汇总
2017/02/28 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
Easyui使用Dialog行内按钮布局的实例
2017/07/27 Javascript
JS获取指定月份的天数两种实现方法
2018/06/22 Javascript
微信小程序实现简单评论功能
2018/11/28 Javascript
JavaScript设计模式之代理模式实例分析
2019/01/16 Javascript
js实现mp3录音通过websocket实时传送+简易波形图效果
2020/06/12 Javascript
python元组操作实例解析
2014/09/23 Python
在Python中操作字典之update()方法的使用
2015/05/22 Python
微信 用脚本查看是否被微信好友删除
2016/10/28 Python
python微信跳一跳系列之色块轮廓定位棋盘
2018/02/26 Python
python 环境搭建 及python-3.4.4的下载和安装过程
2019/07/20 Python
详解如何从TensorFlow的mnist数据集导出手写体数字图片
2019/08/05 Python
python_array[0][0]与array[0,0]的区别详解
2020/02/18 Python
深入了解Python 方法之类方法 &amp; 静态方法
2020/08/17 Python
python之随机数函数的实现示例
2020/12/30 Python
Myprotein蛋白粉美国官网:欧洲畅销运动营养品牌
2016/11/15 全球购物
博朗(Braun)俄罗斯官方商店:德国小家电品牌
2019/09/24 全球购物
中专生自荐信
2014/06/25 职场文书
护士节演讲稿开场白
2014/08/25 职场文书
欠款纠纷起诉状
2015/05/19 职场文书
通讯稿格式及范文
2015/07/22 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
如何解决.cuda()加载用时很长的问题
2021/05/24 Python
JS轻量级函数式编程实现XDM二
2022/06/16 Javascript