Sys.ScriptLoader与JS加载进度条的实现(3)
点击次数:28 次 发布日期:2008-11-26 12:31:01 作者:源代码网
|
源代码网推荐 源代码网推荐 首先是aspx文件。 源代码网推荐 源代码网推荐 1<%@ Page Language="C#" %> 源代码网推荐 2 源代码网推荐 3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 源代码网推荐 4 源代码网推荐 5<script runat="server"> 源代码网推荐 6 源代码网推荐 7</script> 源代码网推荐 8 源代码网推荐 9<html xmlns="http://www.w3.org/1999/xhtml" > 源代码网推荐 10<head runat="server"> 源代码网推荐 11 <title>Load Scripts</title> 源代码网推荐 12 <script language="javascript"> 源代码网推荐 13 function Load() 源代码网推荐 14 { 源代码网推荐 15 document.getElementById("bar").style.width = "0px"; 源代码网推荐 16 var scripts = new Array(); 源代码网推荐 17 for (var i = 0; i < 8; i++) 源代码网推荐 18 { 源代码网推荐 19 var s = new Object(); 源代码网推荐 20 var sleep = Math.round((Math.random() * 400)) + 100; 源代码网推荐 21 s.url = "Script.ashx?sleep=" + sleep + "&t=" + Math.random(); 源代码网推荐 22 s.cost = sleep; 源代码网推荐 23 scripts.push(s); 源代码网推荐 24 } 源代码网推荐 25 源代码网推荐 26 Jeffz.Sample.LoadScripts.load(scripts); 源代码网推荐 27 } 源代码网推荐 28 </script> 源代码网推荐 29</head> 源代码网推荐 30<body style="font-family: Arial;"> 源代码网推荐 31 <form id="form1" runat="server"> 源代码网推荐 32 <div> 源代码网推荐 33 <atlas:ScriptManager ID="ScriptManager1" runat="server"> 源代码网推荐 34 <Scripts> 源代码网推荐 35 <atlas:ScriptReference Path="js/LoadScripts.js" /> 源代码网推荐 36 </Scripts> 源代码网推荐 37 </atlas:ScriptManager> 源代码网推荐 38 源代码网推荐 39 Progress Bar: 源代码网推荐 40 <div style="border: solid 1px black;"> 源代码网推荐 41 <div id="bar" style="height: 20px; width:0%; background-color:Red;"></div> 源代码网推荐 42 </div> 源代码网推荐 43 <input type="button" onclick="Load()" value="Load" /> 源代码网推荐 44 <div id="message"></div> 源代码网推荐 45 </div> 源代码网推荐 46 </form> 源代码网推荐 47</body> 源代码网推荐 48</html> 源代码网推荐 非常的简单。使用两个DIV制作了一个最简单的进度条。在点击按钮时调用了Load()函数。该函数随机生成了Script链接并生成了一个8元素的scripts数组。scripts数组的格式如下: 源代码网推荐 源代码网推荐 1var scripts = 源代码网推荐 2[ 源代码网推荐 3 { url : "http://www.sample.com/sample1.js", cost : costOfLoading1 }, 源代码网推荐 4 { url : "http://www.sample.com/sample2.js", cost : costOfLoading2 }, 源代码网推荐 5 { url : "http://www.sample.com/sample3.js", cost : costOfLoading3 } 源代码网推荐 6]; 源代码网推荐 每个元素的url属性不必说,而cost的功能就是表示加载该文件所消耗的时间的值。这个值没有单位,用到的只是这个值在总共消耗里的比例。另外,可以看到有一个Script.ashx,其作用是模拟一个长时间script加载,它会根据querystring中的sleep的值将线程休眠一段时间(至于后面的t,目的只是通过改变querystring来避免点击按钮时浏览器的缓存),这个文件几乎没有代码,可以在范例下载中看到它的实现。最后通过调用Jeffz.Sample.LoadScripts.load方法进行加载,这就涉及到了下面的代码,LoadScripts.js: 源代码网推荐 源代码网推荐 1Type.registerNamespace("Jeffz.Sample"); 源代码网推荐 2 源代码网推荐 3Jeffz.Sample.LoadScripts = new function() 源代码网推荐 4{ 源代码网推荐 5 var totalCost = 0; 源代码网推荐 6 var scriptLoader = new Sys.ScriptLoader(); 源代码网推荐 7 源代码网推荐 8 this.load = function(scripts) 源代码网推荐 9 { 源代码网推荐 10 if (Jeffz.Sample.__onScriptLoad != null) 源代码网推荐 11 { 源代码网推荐 12 throw new Error("In progress"); 源代码网推荐 13 } 源代码网推荐 14 源代码网推荐 15 totalCost = 0; 源代码网推荐 16 Jeffz.Sample.__onScriptLoad = onScriptLoad; 源代码网推荐 17 var references = new Array(); 源代码网推荐 18 源代码网推荐 19 var loadedCost = 0; 源代码网推荐 20 for (var i = 0; i < scripts.length; i++) 源代码网推荐 21 { 源代码网推荐 22 totalCost += scripts[i].cost; 源代码网推荐 23 loadedCost += scripts[i].cost; 源代码网推荐 24 源代码网推荐 25 var ref = createReference(scripts[i].url, loadedCost); 源代码网推荐 26 源代码网推荐 27 references.push(ref); 源代码网推荐 28 } 源代码网推荐 29 源代码网推荐 30 scriptLoader.load(references, onComplete); 源代码网推荐 31 } 源代码网推荐 32 源代码网推荐 33 function createReference(url, loadedCost) 源代码网推荐 34 { 源代码网推荐 35 var ref = new Object(); 源代码网推荐 36 ref.url = url; 源代码网推荐 37 ref.onscriptload = "Jeffz.Sample.__onScriptLoad("" + url + "", " + loadedCost + ")"; 源代码网推荐 38 return ref; 源代码网推荐 39 } 源代码网推荐 40 源代码网推荐 41 function onComplete() 源代码网推荐 42 { 源代码网推荐 43 Jeffz.Sample.__onScriptLoad = null; 源代码网推荐 44 } 源代码网推荐 45 源代码网推荐 46 function onScriptLoad(url, loadedCost) 源代码网推荐 47 { 源代码网推荐 48 var progress = 100.0 * loadedCost / totalCost; 源代码网推荐 49 document.getElementById("bar").style.width = progress + "%"; 源代码网推荐 50 document.getElementById("message").innerHTML += ("<strong>" + url + "</strong>" + " loaded.<br />"); 源代码网推荐 51 } 源代码网推荐 52} 源代码网推荐 哎,似乎完全没有必要对代码进行多余的解释。到目前为止,一个简单的Script加载进度条就完成了,相当的简单。代码可以点击这里下载,也可以点击这里查看效果。 源代码网推荐 源代码网推荐 不过事情到此为止了吗?事实上,我对这个Solution不怎么满意,虽然对于大多数情况应该已经够用了。可以注意到,我将Jeffz.Sample.LoadScripts实现成为了一个Singleton,也就是说,没有另外一个和它一样的实例。并且在load方法的一开始就判断是不是正在加载,如果是,那么会抛出一个异常。实现了这么一种“单线程”的加载,直接原因是受限于Sys.ScriptLoader的实现。 源代码网推荐 源代码网推荐 请看Sys.ScriptLoader代码的第44行,它使用了eval来“邪恶”地进行了script加载完成时的回调。这其实对于开发人员是一种非常难受的实现,因为eval,所以无法地将一个函数的引用作为回调函数来传递。唯一能做的就是只能把“根代码”作为字符串形式来交给Sys.ScriptLoader。虽然还是能够通过Sys.ScriptLoader实现“并发”的Script加载(说白了最多像Sys.ScriptLoader一样建一个队列嘛),但是代码量自然而然就上去了,开发的复杂度也提高了。 源代码网推荐 源代码网推荐 不过我认为,这种“单线程”的script加载已经足够用于大多数情况了。而且如果真的有“特殊”要求,参照Sys.ScriptLoader这个如此清晰明了的范例,自己重新写一个对于广大开发人员来说,难道还不是易如反掌的事情吗? 源代码网推荐 http://www.cnblogs.com/JeffreyZhao/archive/2006/09/13/502357.html 源代码网推荐 源代码网推荐 源代码网推荐 源代码网推荐 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
