在之前的Promise应用场景与模块化尝试一文中提到过,图片加载之前用img.complete作为判断来决定是否异步加载图片,但是img.complete并不是特别靠谱的属性,所以再写一篇关于complete属性的文章,探究该属性的根源。
src与onload
例子1:1
2
3
4
5
6var img = new Image();
img.src = "logo.jpg";
img.onload = function () {
alert("image is loaded");
};
document.body.appendChild(img);
例子2:1
2
3
4
5
6var img = new Image();
img.onload = function () {
alert("image is loaded");
};
img.src = "logo.jpg";
document.body.appendChild(img);
IE9以下(IE < 9)的版本,例子1中的代码无法正常弹出.Chrome和Firefox下正常
因为logo.jpg是本地图片,导致浏览器加载起来非常快,几乎在给img赋值src的时候,图片就已经加载完成,同时触发了onload事件,代码中为onload赋值的语句就相当于在onload事件发生后,这时候已经晚了.所以正确的写法应该是第2个例子.既在给图片分配地址前,先绑定好它的onload事件,这样就不用担心错过时机的问题了.
缓存与onload
经过测试,IE7以上(>=7),Chrome,Firefox无论存不存在缓存,都会触发onload事件.
complete与onload
例子3:1
2
3
4
5
6
7
8
9
10
11
12
13function doIt () {
alert('do the job!');
}
img.src = "logo.jpg";
if (img.complete) {
alert("image is complete");
doIt();
} else {
img.onload = function () {
alert("image is loaded");
doIt();
};
}
Complete
1 | The IDL attribute complete must return true if any of the following conditions is true: |
上述四种情况都会导致complete变成true,而且complete在脚本执行的过程中可能会动态变化.
经过测试发现,如果src是有效的地址,那么IE,Chrome,Firefox行为一致:
1.IE 7-Edge,Chrome,Firefox 更改src后1
2立刻输出 complete === false
1s后输出 complete === true
如果src是无效地址,那么img.complete的值在不同浏览器下会有区别
1.IE 7-Edge 更改src后1
2立刻输出 complete === false
1s后输出 complete === false
2.Chrome,Firefox 更改src后1
2立刻输出 complete === false
1s后输出 complete === true
例子3能成功的原因是因为它是属于complete为true的情况之一,也就是completely available。假如是其他三种情况下或者是IE的不规范行为,都可能造成例子3的不一致。
总结
- onload函数要写在改变src前,这样确保了onload函数一定会被调用
- complete只是变向的在判断img是否已经触发了load事件,而且是不精准的判断
- complete在不同浏览器下,表现不一致,不建议使用
- 无论浏览器是否存在图片缓存,重新请求图片地址,都会触发onload事件
最后,如果有此类需求,建议采用例2中的代码,先绑定onload事件,在给定src值。