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 相关文章推荐
Jquery下:nth-child(an+b)的使用注意
May 28 Javascript
Js日期选择自动填充到输入框(界面漂亮兼容火狐)
Aug 02 Javascript
jquery的attr方法禁用表单元素禁用输入内容
Jun 23 Javascript
js时间日期格式化封装函数
Dec 02 Javascript
javascript拖拽效果延伸学习
Apr 04 Javascript
使用jQuery实现简单的tab框实例
Aug 22 jQuery
客户端(vue框架)与服务器(koa框架)通信及服务器跨域配置详解
Aug 26 Javascript
input type=file 选择图片并且实现预览效果的实例
Oct 26 Javascript
js推箱子小游戏步骤代码解析
Jan 10 Javascript
VScode格式化ESlint方法(最全最好用方法)
Sep 10 Javascript
Node.js API详解之 vm模块用法实例分析
May 27 Javascript
vue动态加载SVG文件并修改节点数据的操作代码
Aug 17 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
PHP+jQuery 注册模块开发详解
2014/10/14 PHP
php实现递归的三种基本方式
2020/07/04 PHP
PHP文件上传处理案例分析
2016/10/15 PHP
如何通过PHP实现Des加密算法代码实例
2020/05/09 PHP
PHP的重载使用魔术方法代码实例详解
2021/02/26 PHP
5秒后跳转到另一个页面的js代码
2013/10/12 Javascript
jquery插件开发之实现jquery手风琴功能分享
2014/03/10 Javascript
jquery文本框中的事件应用以输入邮箱为例
2014/05/06 Javascript
javascript实现滚动效果的数字时钟实例
2016/07/21 Javascript
jQuery使用Layer弹出层插件闪退问题
2016/12/22 Javascript
几种响应式文字详解
2017/05/19 Javascript
详解React Native顶|底部导航使用小技巧
2017/09/14 Javascript
代码整洁之道(重构)
2018/10/25 Javascript
JS学习笔记之贪吃蛇小游戏demo实例详解
2019/05/29 Javascript
layui实现数据表格点击搜索功能
2020/03/26 Javascript
JS表格的动态操作完整示例
2020/01/13 Javascript
js实现小时钟效果
2020/03/25 Javascript
返回上一个url并刷新界面的js代码
2020/09/12 Javascript
全面了解python字符串和字典
2016/07/07 Python
python装饰器初探(推荐)
2016/07/21 Python
python数据抓取分析的示例代码(python + mongodb)
2017/12/25 Python
通过python+selenium3实现浏览器刷简书文章阅读量
2017/12/26 Python
浅谈Django学习migrate和makemigrations的差别
2018/01/18 Python
python+pandas+时间、日期以及时间序列处理方法
2018/07/10 Python
flask入门之表单的实现
2018/07/18 Python
Python3+Appium实现多台移动设备操作的方法
2019/07/05 Python
python创建学生成绩管理系统
2019/11/22 Python
keras小技巧——获取某一个网络层的输出方式
2020/05/23 Python
python中return不返回值的问题解析
2020/07/22 Python
python制作抽奖程序代码详解
2021/01/15 Python
函授本科自我鉴定
2013/11/03 职场文书
大四本科生的自我评价
2013/12/30 职场文书
个人党性分析材料
2014/12/19 职场文书
2015中学教学工作总结
2015/07/22 职场文书
网络新闻该怎么写?这些写作技巧你都知道吗?
2019/08/26 职场文书
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
2022/05/25 SQL Server