JavaScript Image对象onload事件与complete属性跨浏览器行为解析
本文深入探讨JavaScript中Image对象的onload事件触发机制及complete属性在不同浏览器(IE、Opera、Firefox、Chrome)中的行为差异。通过代码测试发现,事件绑定顺序对onload触发至关重要,且各浏览器对缓存图片的complete状态判断逻辑存在显著不同,IE依赖显示状态而Firefox/Chrome依赖缓存命中。
Image对象onload事件与complete属性跨浏览器行为解析
在使用jQuery插件aeImageResize时,发现其优势在于每张图片加载完成后能立即进行等比缩放。
这一功能主要得益于图片对象Image的onload加载事件。
查阅该插件源码后发现,它同时依赖图片对象的complete属性和onload事件,并针对IE6进行了特殊处理。那么,IE6在图片加载对象的行为上与其他浏览器究竟有何不同?
下文将对此进行详细分析。
通过JavaScript操作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”事件?是否与缓存机制有关?
而在Firefox和Chrome中,每次点击按钮都会加载并显示一张该图片。
稍微修改一下代码:
代码如下:
<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。
令人疑惑的是Firefox,其中Imgttmt.complete的值一直是true;
更令人困惑的是Chrome,它是在最初new Imgttmt()的时候Imgttmt.complete值为false。而之后Imgttmt.complete值就一直为true了!
如果换一张从来没有加载过的图片,Firefox和Chrome的行为就一致了,都是一开始加载时,Imgttmt.complete值为false,之后为true!
测试的过程中还发现,脚本的执行顺序的确会影响到类似于onload等事件的追加,如果在其显示后再追加事件就没有什么实际意义了!
基于JavaScript这种解释性语言的特性,在追加事件的时候一定要注意把事件追加在触发该事件的句柄之前。
JavaScript将图片转换为Base64编码的两种途径
2026-11-05 16:43:05
怎么在 Vue 或 React 项目中正确集成 animate.js
2026-11-05 10:23:38
JS注册事件:addEventListener基础语法与参数详解
2026-11-05 08:44:56
JSP和JS的区别:运行环境与服务端/客户端职责解析
2026-11-04 23:34:36
pdf.js 官方下载地址:GitHub Release 获取预编译包
2026-11-04 23:07:27
