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 相关文章推荐
HTML TO JavaScript 转换
Jun 26 Javascript
IE浏览器打印的页眉页脚设置解决方法
Dec 08 Javascript
jquery禁止输入数字以外的字符的示例(纯数字验证码)
Apr 10 Javascript
jQuery将多条数据插入模态框的示例代码
Sep 25 Javascript
JavaScript  event对象整理及详细介绍
Oct 10 Javascript
JavaScript实现类似淘宝的购物车效果
Mar 16 Javascript
javascript基本数据类型和转换
Mar 17 Javascript
详解Vue学习笔记进阶篇之列表过渡及其他
Jul 17 Javascript
node中的cookie的具体使用
Sep 13 Javascript
Element 默认勾选表格 toggleRowSelection的实现
Sep 04 Javascript
vue项目强制清除页面缓存的例子
Nov 06 Javascript
vue+elementUI组件table实现前端分页功能
Nov 15 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函数import_request_variables()用法分析
2016/04/02 PHP
使用JavaScript创建新样式表和新样式规则
2016/06/14 PHP
php中Redis的应用--消息传递
2017/03/28 PHP
PHP实现的mysql操作类【MySQL与MySQLi方式】
2017/10/07 PHP
获取任意Html元素与body之间的偏移距离 offsetTop、offsetLeft (For:IE5+ FF1 )[
2006/12/22 Javascript
JavaScript 高效运行代码分析
2010/03/18 Javascript
基于jQuery实现表格数据的动态添加与统计的代码
2011/01/31 Javascript
js限制文本框只能输入整数或者带小数点的数字
2015/04/27 Javascript
jquery中map函数遍历数组用法实例
2015/05/18 Javascript
C#中使用迭代器处理等待任务
2015/07/13 Javascript
ArtEditor富文本编辑器增加表单提交功能
2016/04/18 Javascript
node.js文件上传处理示例
2016/10/27 Javascript
Angular路由简单学习
2016/12/26 Javascript
详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)
2017/02/10 Javascript
Javascript实现的StopWatch功能示例
2017/06/13 Javascript
js实现动态增加文件域表单功能
2018/10/22 Javascript
一个小时快速搭建微信小程序的方法步骤
2019/04/15 Javascript
Electron vue的使用教程图文详解
2019/07/05 Javascript
python里使用正则的findall函数的实例详解
2017/10/19 Python
Python中logging.NullHandler 的使用教程
2018/11/29 Python
Pytorch提取模型特征向量保存至csv的例子
2020/01/03 Python
python自动下载图片的方法示例
2020/03/25 Python
opencv python 图片读取与显示图片窗口未响应问题的解决
2020/04/24 Python
基于python模拟bfs和dfs代码实例
2020/11/19 Python
python爬虫判断招聘信息是否存在的实例代码
2020/11/20 Python
一款纯css3制作的2015年元旦雪人动画特效教程
2014/12/29 HTML / CSS
把富文本的回车转为br标签
2019/08/09 HTML / CSS
印度婴儿用品在线商店:Firstcry.com
2016/12/05 全球购物
Foot Locker英国官网:美国知名运动产品零售商
2019/02/21 全球购物
摩飞电器俄罗斯官方网站:Morphy Richards俄罗斯
2020/07/30 全球购物
大学考试作弊检讨书
2014/01/30 职场文书
彩妆大赛策划方案
2014/05/13 职场文书
党员学习中共十八大报告思想汇报
2014/09/15 职场文书
车辆委托书范本
2014/10/05 职场文书
秋菊打官司观后感
2015/06/03 职场文书
分享几种python 变量合并方法
2022/03/20 Python