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 相关文章推荐
fckeditor 获取文本框值的实现代码
Feb 09 Javascript
解决jquery .ajax 在IE下卡死问题的解决方法
Oct 26 Javascript
JS控制表格实现一条光线流动分割行的方法
Mar 09 Javascript
Jquery左右滑动插件之实现超级炫酷动画效果附源码下载
Dec 02 Javascript
干货分享:让你分分钟学会javascript闭包
Dec 25 Javascript
详解JavaScript中this关键字的用法
May 26 Javascript
JS实现随机颜色的3种方法与颜色格式的转化
Jan 05 Javascript
jquery easyui如何实现格式化列
Jul 30 jQuery
利用vue组件自定义v-model实现一个Tab组件方法示例
Dec 06 Javascript
通过一次报错详细谈谈Point事件
May 17 Javascript
解决webpack dev-server不能匹配post请求的问题
Aug 24 Javascript
koa-router源码学习小结
Sep 07 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+swoole+linux实现系统监控和性能优化操作示例
2019/04/15 PHP
php使用Swoole实现毫秒级定时任务的方法
2020/09/04 PHP
懒就要懒到底——鼠标自动点击(含时间判断)
2007/02/20 Javascript
JQuery Highcharts 动态生成图表的方法
2013/11/15 Javascript
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
浅谈轻量级js模板引擎simplite
2015/02/13 Javascript
javascript伸缩型菜单实现代码
2015/11/16 Javascript
HTML页面,测试JS对C函数的调用简单实例
2016/08/09 Javascript
PHP+jquery+ajax实现分页
2016/12/09 Javascript
vue2实现移动端上传、预览、压缩图片解决拍照旋转问题
2017/04/13 Javascript
Vue实战之vue登录验证的实现代码
2017/10/31 Javascript
在微信小程序中渲染HTML内容的方法示例
2018/09/28 Javascript
基于Vue中使用节流Lodash throttle详解
2019/10/30 Javascript
从零开始在vue-cli4配置自适应vw布局的实现
2020/06/08 Javascript
Vue登录拦截 登录后继续跳转指定页面的操作
2020/08/04 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
2020/08/26 Javascript
[03:37]2016完美“圣”典 风云人物:Mikasa专访
2016/12/07 DOTA
Python3通过Luhn算法快速验证信用卡卡号的方法
2015/05/14 Python
python转换字符串为摩尔斯电码的方法
2015/07/06 Python
python字典多键值及重复键值的使用方法(详解)
2016/10/31 Python
python3+pyqt5+itchat微信定时发送消息的方法
2019/02/20 Python
Python二进制文件读取并转换为浮点数详解
2019/06/25 Python
Django 后台获取文件列表 InMemoryUploadedFile的例子
2019/08/07 Python
python deque模块简单使用代码实例
2020/03/12 Python
.img/.hdr格式转.nii格式的操作
2020/07/01 Python
python中pickle模块浅析
2020/12/29 Python
深入浅出CSS3 background-clip,background-origin和border-image教程
2011/01/27 HTML / CSS
世界上最大的皮肤科医生拥有和经营的美容网站:LovelySkin
2021/01/03 全球购物
小学生作文评语
2014/04/18 职场文书
求职意向书
2014/07/29 职场文书
2014年计生协会工作总结
2014/11/21 职场文书
四年级小学生评语
2014/12/26 职场文书
农民工工资保障承诺书
2015/05/04 职场文书
陈斌强事迹观后感
2015/06/17 职场文书
Python可视化学习之seaborn绘制矩阵图详解
2022/02/24 Python
聊聊配置 Nginx 访问与错误日志的问题
2022/05/25 Servers