热爱斯诺克的程序员
deng的com世界
博客园
社区
首页
新随笔
联系
管理
订阅
随笔- 3 文章- 1 评论- 39
javascript图片浏览器的核心——图片预加载
网站开发时经常需要在某个页面需要实现对大量图片的浏览,如果考虑流量的话,大可以像pconline一样每个页面只显示一张图片,让用户每看一张图片就需要 重新下载一下整个页面。不过,在web2.0时代,更多人愿意用javascript来实现一个图片浏览器,让用户无需等待过长的时间就能看到其他图片。
知道了一张图片的地址,需要把它在一个固定大小的html容器(可以是div等)里边显示出来,最重要的当然是需要知道这张即将显示的图片的宽和高,然后再结合容器的宽和高,按照一定的缩放比例使图片显示出来。因此,实现图片预加载就成为图片浏览器的核心功能了。
做过图片翻转效果的朋友其实都知道,要让图片轮换的时候不出现等待,最好是先让图片下载到本地,让浏览器缓存起来。这时,一般都会用到js里边的Image对象。一般的手段无非这样:
function
preLoadImg(url)
{
var
img
=
new
Image();
img.src
=
url;
}
通过调用preLoadImg函数,传入图片的url,就能使图片预先下载下来了。实际上,这里用到的预下载功能也和这基本一致。图片预下载下来后,通过 img的width和height属性,就能知道图片的宽和高了。但是需要考虑到,在做图片浏览器功能时,图片都是实时显示的。比如你点了显示的按钮,这 个时候才会调用上边类似的代码来加载图片。因此,如果你直接用img.width的时候,图片还没有完全下载下来。因此,需要用一些异步的方法,等到图片 下载完毕的时候才会再对img的width和height进行调用。
实现这样的异步方法实际上不难,图片的下载完毕事件也很简单,就是简单的onload事件。因此,我们可以写出下面的代码:
function
loadImage(url, callback)
{
var
img
=
new
Image();
img.src
=
url;
img.onload
=
function
()
{
//
图片下载完毕时异步调用callback函数。
callback.call(img);
//
将callback函数this指针切换为img。
}
;
}
好了,再来写一个测试用例。
function imgLoaded(){
alert(this.width);
}
<
input
type
="button"
value
="loadImage"
onclick
="loadImage('aaa.jpg',imgLoaded)"
/>
在firefox中测试一下,发现不错,果然和预想的效果一样,在图片下载后,就会弹出图片的宽度来。无论点击多少次或者刷新结果都一样。
不过,做到这一步,先别高兴太早——还需要考虑一下浏览器的兼容性,于是,赶紧到ie里边测试一下。没错,同样弹出了图片的宽度。但是,再点击load的时候,情况就不一样了,什么反应都没有了。刷新一下,也同样如此。
经过对多个浏览器版本的测试,发现ie6、opera都会这样,而firefox和safari则表现正常。其实,原因也挺简单的,就是因为浏览器的缓存 了。当图片加载过一次以后,如果再有对该图片的请求时,由于浏览器已经缓存住这张图片了,不会再发起一次新的请求,而是直接从缓存中加载过来。对于 firefox和safari,它们视图使这两种加载方式对用户透明,同样会引起图片的onload事件,而ie和opera则忽略了这种同一性,不会引 起图片的onload事件,因此上边的代码在它们里边不能得以实现效果。
怎么办呢?最好的情况是Image可以有一个状态值表明它是否已经载入成功了。从缓存加载的时候,因为不需要等待,这个状态值就直接是表明已经下载了,而从http请求加载时,因为需要等待下载,这个值显示为未完成。这样的话,就可以搞定了。
经过一些分析,终于发现一个为各个浏览器所兼容的Image的属性——complete。所以,在图片onload事件之前先对这个值做一下判断即可。最后,代码变成如下的样子:
function
loadImage(url, callback)
{
var
img
=
new
Image();
//
创建一个Image对象,实现图片的预下载
img.src
=
url;
if
(img.complete)
{
//
如果图片已经存在于浏览器缓存,直接调用回调函数
callback.call(img);
return
;
//
直接返回,不用再处理onload事件
}
img.onload
=
function
()
{
//
图片下载完毕时异步调用callback函数。
callback.call(img);
//
将回调函数的this替换为Image对象
}
;
}
;
经过这么一番折腾,总算是让各个浏览器都能满足我们的目标了。虽然代码很简单,但是却把图片浏览器中最核心的问题解决掉了,接下来你所要做的,仅仅是图片如何呈现的问题了。
posted @ 2008-06-15 15:03
Ronie Deng
阅读(3059)
评论(26)
编辑
收藏
发表评论
回复
引用
查看
#1楼
2008-06-15 18:05 |
PerfectDesign
解决问题的思路非常清晰啊~
楼主文笔不错
回复
引用
查看
#2楼
2008-06-15 22:33 |
姜敏
不错!
回复
引用
查看
#3楼
2008-06-15 22:36 |
梁逸晨
好文一定要顶!
回复
引用
查看
#4楼
2008-06-15 23:39 |
杨正祎(阿一)
不错。
回复
引用
查看
#5楼
2008-06-15 23:45 |
李涛
思路真棒,学习了
回复
引用
#6楼
2008-06-15 23:50 |
xiaoxin_2008 [未注册用户]
学习,佩服lz解决问题的能力!
回复
引用
查看
#7楼
2008-06-15 23:52 |
Ryan Gene
不错,谢谢!收藏一下。
回复
引用
查看
#8楼
2008-06-16 08:28 |
jack-冯俊杰
顶
顶
顶
回复
引用
查看
#9楼
2008-06-16 08:39 |
Solog
学习了
回复
引用
#10楼
2008-06-16 08:44 |
zzticzh2 [未注册用户]
不错 支持!
回复
引用
查看
#11楼
2008-06-16 08:57 |
饥饿的狼
留个名
回复
引用
查看
#12楼
2008-06-16 09:12 |
XeonWell
不错,喜欢跨浏览器实现的东西
一个星期没打斯诺克了,手好痒
回复
引用
查看
#13楼
2008-06-16 09:15 |
peace
短小精悍
回复
引用
查看
#14楼
[
楼主
]2008-06-16 10:19 |
Ronie Deng
想不到第一次在博客园上首页就得到这么多朋友的认同,3ks!希望和大家能有更多的沟通。:-)
回复
引用
查看
#15楼
[
楼主
]2008-06-16 10:53 |
Ronie Deng
中间有两个星期没打过了,昨天终于痛快地打了三四个小时,不过都是打八球,斯诺克水平现在亟待提高。
--引用--------------------------------------------------
XeonWell: 不错,喜欢跨浏览器实现的东西
一个星期没打斯诺克了,手好痒
--------------------------------------------------------
回复
引用
#16楼
2008-06-16 10:58 |
sprite [未注册用户]
那我如果这张图片显示再img中,然后想按比列改变img的大小怎么处理呢?遇到这样的问题的
回复
引用
查看
#17楼
2008-06-16 13:43 |
yuejianjun
能不能把这个javascript图片浏览器的核心——图片预加载 的代码发给我学习一下,谢谢!
回复
引用
#18楼
2008-06-16 14:04 |
学习中 [未注册用户]
回调函数里 ,是什么内容呢?
---
callback.call(img);
回复
引用
#19楼
2008-06-16 14:44 |
学习中 [未注册用户]
--引用--------------------------------------------------
yuejianjun: 能不能把这个javascript图片浏览器的核心——图片预加载 的代码发给我学习一下,谢谢!
--------------------------------------------------------
大侠 ,也发给我学习,学习。谢谢了。
回复
引用
查看
#20楼
2008-06-16 23:00 |
BAsil
顶
回复
引用
#21楼
2008-06-17 02:55 |
编织套管 [未注册用户]
浏览器慪慶捳楲瑰问题。
回复
引用
查看
#22楼
2008-07-01 09:23 |
缪缪
好,很好,顶了
回复
引用
查看
#23楼
2008-08-05 10:13 |
chegan
很好,学习了
回复
引用
查看
#24楼
2008-08-05 11:11 |
小猪凯
这篇文章见过很多了,学习到不少东西.可是哪里是原创?这里是原创么?
回复
引用
查看
#25楼
2008-09-19 10:47 |
簡簡單單..
发现除IE之外, Image对象都不是异步加载的(如FF)
请楼主鉴定下..
^ō^
回复
引用
查看
#26楼
2008-10-01 14:58 |
老飞
正是我想要的啊,试试!
新用户注册
刷新评论列表
标题
姓名
主页
Email
(博主才能看到)
验证码
*
看不清,换一张
[
登录
][
注册
]
内容(请不要发表任何与政治相关的内容)
网站首页
新闻频道
社区
小组
博问
网摘
闪存
找找看
Remember Me?
登录
使用高级评论
新用户注册
返回页首
恢复上次提交
[使用Ctrl+Enter键可以直接提交]
相关文章:
javascript小技巧
“图片变幻显示控件”发布
相关链接:
最新IT新闻:
11个处于悬崖边缘的 Web 公司
扎克博格:Facebook要先赚吆喝后赚钱
金融风暴改写富豪榜排名 巴菲特资产超盖茨
红杉资本发出严重警告:黄金时代已成历史
2008年10月11日科技博客精选
<
2008年10月
>
日
一
二
三
四
五
六
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
与我联系
发短消息
搜索
常用链接
我的随笔
我的空间
我的短信
我的评论
更多链接
我的文章
我的参与
我的新闻
最新评论
我的标签
留言簿
给我留言
查看留言
我的标签
div(1)
右键菜单(1)
随笔分类
java(1)
(rss)
前台
(rss)
随笔档案
2008年10月 (1)
2008年6月 (3)
文章分类
.net
(rss)
Ajax
(rss)
Css
(rss)
Javascript
(rss)
Php
(rss)
相册
文章图片
最新评论
1. re: javascript图片浏览器的核心——图片预加载
正是我想要的啊,试试! (老飞)
2. re: javascript图片浏览器的核心——图片预加载
发现除IE之外, Image对象都不是异步加载的(如FF)
请楼主鉴定下..
^ō^ (簡簡單單..)
阅读排行榜
1. javascript图片浏览器的核心——图片预加载(3059)
2. 让div如右键菜单一样聪明(2599)
3. 一张图片变化多种花样(149)
4. 用 Java 来打造属于自己的Web服务器 (137)
评论排行榜
1. javascript图片浏览器的核心——图片预加载(26)
2. 让div如右键菜单一样聪明(13)
3. 用 Java 来打造属于自己的Web服务器 (0)
4. 一张图片变化多种花样(0)