js 实现图片预加载(js操作 Image对象属性complete ,事件onload 异步加载图片)


Posted in Javascript onMarch 25, 2011

看个例子:

<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 相关文章推荐
解决FireFox下[使用event很麻烦]的问题
Nov 26 Javascript
js chrome浏览器判断代码
Mar 28 Javascript
全面解析Bootstrap表单使用方法(表单样式)
Nov 24 Javascript
Three.js基础学习之场景对象
Sep 27 Javascript
使用validate.js实现表单数据提交前的验证方法
Sep 04 Javascript
微信小程序使用swiper组件实现层叠轮播图
Nov 04 Javascript
vue实现双向绑定和依赖收集遇到的坑
Nov 29 Javascript
mock.js实现模拟生成假数据功能示例
Jan 15 Javascript
vue项目中定义全局变量、函数的几种方法
Nov 08 Javascript
Vue项目接入Paypal实现示例详解
Jun 04 Javascript
vue中渲染对象中属性时显示未定义的解决
Jul 31 Javascript
详解VUE中的插值( Interpolation)语法
Oct 18 Javascript
基于jquery的3d效果实现代码
Mar 23 #Javascript
jquery 操作表格实现代码(多种操作打包)
Mar 20 #Javascript
jQuery实现的Email中的收件人效果(按del键删除)
Mar 20 #Javascript
jquery图片上下tab切换效果
Mar 18 #Javascript
javascript一些实用技巧小结
Mar 18 #Javascript
jquery获取下拉列表的值为null的解决方法
Mar 18 #Javascript
iframe的onload在Chrome/Opera中执行两次Bug的解决方法
Mar 17 #Javascript
You might like
PHP字符串函数系列之nl2br(),在字符串中的每个新行 (\n) 之前插入 HTML 换行符br
2011/11/10 PHP
php按百分比生成缩略图的代码分享
2014/05/10 PHP
ThinkPHP打开验证码页面显示乱码的解决方法
2014/12/18 PHP
PHP 根据key 给二维数组分组
2016/12/09 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
js可突破windows弹退效果代码
2008/08/09 Javascript
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
Jquery取得iframe下内容的方法
2013/11/18 Javascript
jquerydom对象的事件隐藏显示和对象数组示例
2013/12/10 Javascript
jQuery中next()方法用法实例
2015/01/07 Javascript
JQuery插件ajaxfileupload.js异步上传文件实例
2015/05/19 Javascript
使用vue根据状态添加列表数据和删除列表数据的实例
2018/09/29 Javascript
javascript实现一款好看的秒表计时器
2020/09/05 Javascript
Python的Django框架使用入门指引
2015/04/15 Python
简化Python的Django框架代码的一些示例
2015/04/20 Python
微信跳一跳自动运行python脚本
2018/01/08 Python
Python pip替换为阿里源的方法步骤
2019/07/02 Python
python 扩展print打印文件路径和当前时间信息的实例代码
2019/10/11 Python
Python 日志logging模块用法简单示例
2019/10/18 Python
np.newaxis 实现为 numpy.ndarray(多维数组)增加一个轴
2019/11/30 Python
python输出数组中指定元素的所有索引示例
2019/12/06 Python
PyTorch实现ResNet50、ResNet101和ResNet152示例
2020/01/14 Python
新手入门学习python Numpy基础操作
2020/03/02 Python
python爬虫容易学吗
2020/06/02 Python
css3 实现元素弧线运动的示例代码
2020/04/24 HTML / CSS
S’well Bottle保温杯官网:绝缘不锈钢水瓶
2018/05/09 全球购物
英国复古服装购物网站:Collectif
2019/10/30 全球购物
在c#中using和new这两个关键字有什么意义
2013/05/19 面试题
设计部经理的岗位职责
2013/11/16 职场文书
大堂副理的岗位职责范文
2014/02/17 职场文书
能源工程专业应届生求职信
2014/03/01 职场文书
吨的认识教学反思
2014/04/27 职场文书
旅游饭店管理专业自荐书
2014/06/28 职场文书
财政局党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
感恩母亲节活动总结
2015/02/10 职场文书
优秀班主任工作总结2015
2015/05/25 职场文书