请选择 进入手机版 | 继续访问电脑版
收藏本站腾讯微博新浪微博
点点网模板设计大赛 phpchina

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 用悬赏 三天解决问题 解决访问速度慢 论坛支持农历生日 - 给官方提建议

论坛活动及任务 归纳网站最新活动 地图任务 邮件更新任务:保护帐号安全

积分换实物,来参加蓝色理想积分兑换吧! 联系招聘客服 蓝色理想帮你找工作! 万元奖励等你拿——点点网模板设计大赛

查看: 10691|回复: 17

ImageLoader 1.1 Release [复制链接]

dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-9-15 14:18:17 |显示全部楼层
原创作品,禁止转载

By dknt From bbs.blueidea.com

特点:
1.图片预载入,载入后再显示。意图一次呈现,不会让一块一块下载破坏你的页面,绝佳的用户体验,颠覆传统的浏览器呈现图片的处理方式(需要后续函数支持)。
2.不会因载入图片造成脚本暂停假死,完全另一线程进行。不影响主程序流程。
3.提供及时的反馈,包括两方面的内容:1.正在载入什么图片 2.当前的百分数进度。大大提高留住用户眼球的概率,不会让用户因为苦等而离开。
4.容错支持,即使某个图片没有成功下载,也可以设置超时时间以便处理下一个图片。
5.多变的参数类型,尽最大可能方便使用。

  1. // save this as "image_loader.js"

  2. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-//
  3. /*
  4.   ImageLoader, Version 1.1, JavaScript
  5.   (c) 2006 Christian An <anchangsi@gmail.com>

  6.   With copyright not modified, you can use this program freely.
  7. */
  8. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-//

  9. function ImageLoader(className,Options){
  10.         this._ImageLoadStack = null;
  11.         this._currrentLoading = "";
  12.         this._FinalRun = false;
  13.         this.numLoaded = 0;
  14.         this.ClassName = className;
  15.        
  16.         if(typeof(Options)=="undefined") Options = {};
  17.        
  18.         if(isNaN(Options.Timeout) || Options.Timeout < 0 ||  Options.Timeout >100000){
  19.                 this.EnableTimeout = false;
  20.         }else {
  21.                 this.EnableTimeout = true;
  22.                 this.Timeout = Options.Timeout;
  23.         }
  24.        
  25.         if(typeof(Options.func)=="undefined"){
  26.                 this.AfterFunction = null;
  27.         }else{
  28.                 this.AfterFunction = Options.func;
  29.         }
  30.        
  31.         if(typeof(Options.display)=="undefined"){
  32.                 this.disDiv = null;
  33.         }else if(typeof(Options.display)=="string"){
  34.                 this.disDiv = document.getElementById(Options.display);
  35.         }else if(typeof(Options.display)=="object"){
  36.                 this.disDiv = Options.display;
  37.         }else{
  38.                 this.disDiv = null;
  39.         }

  40.         if(typeof(Options.process)=="undefined"){
  41.                 this.procDiv = null;
  42.         }else if(typeof(Options.process)=="string"){
  43.                 this.procDiv = document.getElementById(Options.process);
  44.         }else if(typeof(Options.process)=="object"){
  45.                 this.procDiv = Options.process;
  46.         }else{
  47.                 this.procDiv = null;
  48.         }

  49.        
  50.         if(typeof(document.imageArray)=="undefined") document.imageArray = new Array();
  51.        
  52.         this.Load = function(){
  53.                 var args = this.Load.arguments;
  54.                 if(args.length!=0){
  55.                         this._ImageLoadStack = new Array();
  56.                         for(i=0; i<args.length; i++){
  57.                                 if(args[i].indexOf("#")!=0){
  58.                                         this._ImageLoadStack.push(args[i]);
  59.                                 }
  60.                         }

  61.                 }else if(this._ImageLoadStack == null){
  62.                         this._runFinal();
  63.                 }
  64.                 this.numTotal = this._ImageLoadStack.length;
  65.                 this._LoadAImage();
  66.         }
  67.        
  68.         this._LoadAImage = function(){
  69.                 if(this._ImageLoadStack.length!=0){
  70.                         var sURL = this._ImageLoadStack.shift();
  71.                         if(this.disDiv!=null) this.disDiv.innerHTML = sURL;
  72.                         _currrentLoading = sURL;
  73.                
  74.                        
  75.                         var j = document.imageArray.length;
  76.                         document.imageArray[j] = document.createElement("IMG");
  77.                         document.imageArray[j].Owner = this;
  78.                        
  79.                         document.imageArray[j].onload = function(){
  80.                                 this.Owner._LoadAImage();
  81.                                 this.onload = null;
  82.                         }
  83.                         document.imageArray[j].onerror = function(){
  84.                                 this.Owner._LoadAImage();
  85.                                 this.onload = null;
  86.                         }
  87.                        
  88.                         if(this.EnableTimeout){
  89.                                 window.setTimeout("if(_currrentLoading==\""+sURL+"\"){"+this.ClassName+"._LoadAImage()}",this.Timeout);
  90.                         }
  91.        
  92.                         document.imageArray[j].src = sURL;
  93.                                 if(this.procDiv!=null){
  94.                                 this.numLoaded++;
  95.                                 var percentage = Math.floor(this.numLoaded * 100 / this.numTotal);
  96.                                 this.procDiv.innerHTML = percentage;
  97.                         }

  98.                 }else{
  99.                         this._runFinal();
  100.                 }

  101.         }
  102.         this._runFinal = function(){
  103.                         if(this._FinalRun == false){
  104.                                 this._FinalRun = true;
  105.                                
  106.                                 if(typeof(this.AfterFunction)=="function"){
  107.                                         this.AfterFunction();
  108.                                 }else if(typeof(this.AfterFunction)=="string"){
  109.                                         if (window.execScript){
  110.                                                 window.execScript(this.AfterFunction);
  111.                                         }else{
  112.                                                 window.eval(this.AfterFunction);
  113.                                         }
  114.                                 }
  115.                         }
  116.         }
  117.         this.setLoadImages = function(imageArray){
  118.                 if(typeof(imageArray)!="object") return;
  119.                 this._ImageLoadStack = imageArray;
  120.         }

  121. }
复制代码


[Document]

使用
  1. var loader = new ImageLoader(ClassName,Options);
复制代码


的形式创建该对象。

其中:

loader : 为 JavaScript 变量名;

ClassName : String 型: 为 loader 在 JavaScript 中的表达。 如果是在任何函数之外创建该对象,请直接赋以该变量的字符串形式,如对应loader 为"loader" ; 如果是某个函数体内,仍然赋以该变量的字符串形式,但是创建的变量名请使用 window.loader 的形式。

Options   : Object 型,下列属性是支持的:
                Timeout : Integer,可选。取值为1-100000,单位毫秒。非正整数表示不采用。此为一个图片的最大载入时间,如果提供这个参数,则某个图片不能正常下载时,可以跳过继续下载另一个图片。否则将一直等到该图片下载完成为止。
                func      : Function / String,必须。当所有图片载入之后调用的函数,通常是一个显示这些图片功能的函数。如果不提供这个函数,则整个机制将变得毫无作用。 Function型的参数会直接调用,String型的参数会当作JavaScript 语句来运行。
                display   :String / Object,可选。此为显示当前载入图片的DOM对象,该对象应该支持innerHTML属性。 当提供此参数为String 时,会被当作DOM对象的 id 来处理,若 Object 型,则直接当作一个DOM对象。提供其他类型没有效果。
                process  :String / Object,可选。此为以百分数显示当前载入进度的DOM对象,该对象应该支持innerHTML属性。 当提供此参数为String 时,会被当作DOM对象的 id 来处理,若 Object 型,则直接当作一个DOM对象。提供其他类型没有效果。
见下列示范:
  1. //在所有函数之外时
  2. //function final(){...};
  3. function $(par){
  4.         return document.getElementById(par)
  5. }

  6. var MyLoader = new ImageLoader("MyLoader ",{Timeout:1000,func: final,display:"display",process:$("process")});


  7. //在某个函数体内时
  8. function somefunc(){
  9.    //...
  10.    window.MyLoader = new ImageLoader("MyLoader ",{Timeout:1000,func: "alert('fine')",display:"display",process:$("process")});
  11.   //...
  12. }
复制代码


=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*=*-*

方法定义:
Load(paralist)  :载入一系列图片。完毕后自动调用 func属性的内容。 paralist,可以是一些字符串的集合(但不要提供一个数组),各项由 , 隔开。这些字符串应该是图片的url。也可以不提供任何参数。Load方法将载入预先设定好的系列图片。如果没有预先设定过,则直接调用 func 属性的内容。若func没有提供,则没有任何效果。
  1. //sample:
  2. MyLoader.Load("http://bbs.blueidea.com/images/blue/logo.gif",
  3.                         "http://gg.blueidea.com/2006/chinaok/208x32.gif",
  4.                         "http://gg.blueidea.com/2006/now/208x32.gif",
  5.                         "http://gg.blueidea.com/2006/gongyi/banner.jpg",
  6.                         "http://gg.blueidea.com/2006/flash8/pepsi.gif",
  7.                         "http://www.google.com/intl/zh-CN_ALL/images/logo.gif");

  8. //or if pic series is provided.

  9. MyLoader.Load();
复制代码


setLoadImages(ArrayImages): 设定要载入的图片系列。ArrayImages 应以数组的形式提供,数组的每一个元素都应当是一个图片的URL。不接受其他类型的参数。此方法调用后并不开始载入图片。

  1. //sample:
  2. MyLoader.setLoadImages(["http://bbs.blueidea.com/images/blue/logo.gif",
  3.                         "http://gg.blueidea.com/2006/chinaok/208x32.gif",
  4.                         "http://gg.blueidea.com/2006/now/208x32.gif",
  5.                         "http://gg.blueidea.com/2006/gongyi/banner.jpg",
  6.                         "http://gg.blueidea.com/2006/flash8/pepsi.gif",
  7.                         "http://www.google.com/intl/zh-CN_ALL/images/logo.gif"])
复制代码


---------------------------------------------------------------------------------------------------------------------------------------------
[测试用例]

 提示:您可以先修改部分代码再运行



欢迎大家使用并且帮忙找bug. xx

[ 本帖最后由 dknt 于 2006-10-19 20:29 编辑 ]
已有 1 人评分威望 收起 理由
Sheneyan + 2 原创内容

总评分: 威望 + 2   查看全部评分

- 回帖取义,发帖成仁... -
西部数码顶级域名注册商39元抢注!

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2006-9-16 00:17:57 |显示全部楼层
你不该使用onreadystatechange ,并不是所有的浏览器都支持img的这个事件,比如firefox :)

个人觉得使用保守一点的onload会比较好。

以前我也发过两篇类似的内容,也许可以看看。

你的帖子不错,也介绍得很详细,加分鼓励,如果将效果延续到firefox下那就更好(精华伺候:D)
租服务器,上51IDC | [长沙]招聘:PHP经理10K/WEB前端6K/PHP开发6K

使用道具 举报

一滩死水

钻石会员

帖子
1063
体力
7305
威望
0
发表于 2006-9-16 10:55:30 |显示全部楼层
精华伺候..  -_\\
我一直哭一直哭,哭我没鞋穿。直到有一天我看到一个人,他连脚也没有……

使用道具 举报

bound0 

老饕

版主 手机认证 

帖子
6592
体力
8778
威望
287
发表于 2006-9-16 12:26:56 |显示全部楼层
考虑得挺周全的,不过还是提点儿建议:

可能你的侧重点在于整体统筹多个图片的预载效果,从你的代码来看,应用时是让使用者自己写代码来解决具体的显示方式,如果不提供func属性的话,则什么也不会做。

既然是这样的话,调用的机制就有点问题了:

你没有给Function型的func属性提供参数,这样就不太好用了。

而且或许你应该提供一种没有func属性时的默认显示方式,否则你要求调用时提供display这个属性就显得多余了。
[Bound0 专题列表]
Pas besoin de gril : l'enfer, c'est les Autres.

使用道具 举报

bound0 

老饕

版主 手机认证 

帖子
6592
体力
8778
威望
287
发表于 2006-9-16 12:46:11 |显示全部楼层
“你没有给Function型的func属性提供参数”

我这话大概是有歧义。我的意思是,用一个函数fun(xx,yy)去充当你的func属性时,这个函数的参数表怎么设?

“不需要 将 display 和 func 作关连。没有这么设计,display 只是提供一个显示当前载入什么东西的可能。”

这话不明白,没看到实现了什么可能啊?

[ 本帖最后由 bound0 于 2006-9-16 12:47 编辑 ]
[Bound0 专题列表]
Pas besoin de gril : l'enfer, c'est les Autres.

使用道具 举报

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2006-9-19 02:53:00 |显示全部楼层
没时间细看,大概过了一遍,加精伺候

使用道具 举报

dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-9-19 03:18:19 |显示全部楼层
哈,多谢拉~ 下周有空再弄一个
- 回帖取义,发帖成仁... -

使用道具 举报

nsnake 
帖子
38
体力
114
威望
0
发表于 2006-9-19 16:27:21 |显示全部楼层
不能支持FF
可惜阿

使用道具 举报

dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-9-19 18:20:54 |显示全部楼层
原帖由 nsnake 于 2006-9-19 16:27 发表
不能支持FF
可惜阿



可以支持 FF,我改过了。FF 对缓存的利用让人惊讶得好。所以第二次运行测试用例之前一定要清一下缓存,否则看不出什么效果。



很抱歉没有带注释的,但是有疑问一定解决。

[ 本帖最后由 dknt 于 2006-9-19 18:26 编辑 ]
- 回帖取义,发帖成仁... -

使用道具 举报

dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-10-14 12:34:59 |显示全部楼层
主要用于图片的预载入
1.图片预载入,载入后再显示。意图一次呈现,不会让一块一块下载破坏你的页面
- 回帖取义,发帖成仁... -

使用道具 举报

asfman 
帖子
586
体力
2647
威望
0
发表于 2006-10-17 23:43:06 |显示全部楼层
1。我觉得你这里用setTimeout 函数很别扭.会不停地并发调用setTimeout。
2。document.imageArray[j++].src = sURL;这里的j++有什么意义?好象直接document.imageArray[j].src就可以了吧?
3。                        document.imageArray[j].onload = function(){
                                this.Owner._LoadAImage();
                                this.onload = null;
                        }我觉得这个this.onload=null似乎没有任何意义,下面onerror里也是,你觉得呢?
4。
人有多大胆  地有多大产
没有做不到  只有想不到

使用道具 举报

myhyli 

卖坏梨

荣誉管理 手机认证 

帖子
11865
体力
53501
威望
220
居住地
浙江省 杭州市
发表于 2006-10-18 09:05:30 |显示全部楼层
onload=null是为了动画gif,不加这个,动画gif每循环一次都会触发一次

使用道具 举报

asfman 
帖子
586
体力
2647
威望
0
发表于 2006-10-18 10:37:19 |显示全部楼层
原来如此,那1 2 呢
人有多大胆  地有多大产
没有做不到  只有想不到

使用道具 举报

asfman 
帖子
586
体力
2647
威望
0
发表于 2006-10-18 23:55:19 |显示全部楼层
还有我在最后加
for(var i=0;i<document.imageArray.length;i++)
document.body.appendChild(document.imageArray)
为什么上面100完成了,图片只显示一张其他会不显示?而要按一下游览器的转到按钮才有

 提示:您可以先修改部分代码再运行


[ 本帖最后由 asfman 于 2006-10-18 23:59 编辑 ]
人有多大胆  地有多大产
没有做不到  只有想不到

使用道具 举报

gway 
帖子
83
体力
184
威望
0
居住地
广东省 广州市
发表于 2006-10-19 08:46:09 |显示全部楼层
呵呵

等到具体应用吧
努力学习中。。。

使用道具 举报

dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-10-19 20:22:52 |显示全部楼层

抱歉,才看到.

1。我觉得你这里用setTimeout 函数很别扭.会不停地并发调用setTimeout。
    不会吧, 对于每个图片只会运行一次。setTimeout 只运行一次,运行一次之后就不会再执行了;setInterval才间断执行。这个地方主要是为了超时的时候能推动一下。免得卡死在一个图片上。

2。document.imageArray[j++].src = sURL;这里的j++有什么意义?好象直接document.imageArray[j].src就可以了吧?
  写错了,抱歉,确实没有必要的。程序最初是while结构,忘了改了。

3。                     document.imageArray[j].onload = function(){
                            this.Owner._LoadAImage();
                            this.onload = null;
                     }我觉得这个this.onload=null似乎没有任何意义,下面onerror里也是,你觉得呢?

myhyli 说的有道理。不过我当初不是这么想的,现在发现可能考虑错了。这段程序有点问题,容我再改一改。


还有我在最后加
for(var i=0;i<document.imageArray.length;i++)
document.body.appendChild(document.imageArray)
为什么上面100完成了,图片只显示一张其他会不显示?而要按一下游览器的转到按钮才有

你可能没太理解它的运作流程,仅仅这样并不能显示出来那些图片,因为图片还没有加载完。你应该在func参数中设置要运行的后续显示函数。我的程序的重点就是在于加载的同步 ,为了能够同步,必须先让加载过程运行完毕。换句话说,你在for(var i=0;i<document.imageArray.length;i++)时,loader并没有运行完成,可能那时 imageArray 里 确实只有一个图片。
- 回帖取义,发帖成仁... -

使用道具 举报

asfman 
帖子
586
体力
2647
威望
0
发表于 2006-10-19 22:04:51 |显示全部楼层
关于 1比如有个函数funtion a(){
                             if(当时间为1秒) a();
                              setTimeout("a()",2000);
                                }
那么1秒后会掉用a() 记作a_1() 2秒后会setTimeout会调用a(),新的a_1()也会调用a(),然后3秒后。。。后来并发越来越多
人有多大胆  地有多大产
没有做不到  只有想不到

使用道具 举报

dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-10-25 23:20:55 |显示全部楼层
楼上的,你给出的那个函数和我的有一致性,但是你忽略了一个细节。

我的函数中 if(this._ImageLoadStack.length!=0)  这个条件限制了 setTimeout 不会一直运行到。

a() a_1()  .. a_n()  确实存在,但是 n 是有界的,它等于要载入的图片数。
有两点要提示一下;
一,a_i 运行时 a_i+1 不一定会被setTimeout运行,是否运行取决于图片是不是还在下载中(if(_currrentLoading==\""+sURL+"\") ),但是a_j ( j > i + 1) 也有机会触发 a_j+1 。

二,而且前后两者之间是有间隔的,如果Timeout不要设的太小,图片不要下载太快,不可能出现并发。
- 回帖取义,发帖成仁... -

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|安久科技提供CDN|blueidea.com ( 京ICP备05002321号 )  

GMT+8, 2012-2-11 21:17 , Processed in 0.116937 second(s), 11 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部