技术开发 频道

Sys.ScriptLoader与JS加载进度条的实现


【IT168技术文档】

  Atlas中有个类:Sys.ScriptLoader,它的作用就是在页面中依次地加载多个Script文件。在实现之前,先来分析一下这个类的代码。
1Sys.ScriptLoader = function() { 2 3 // 所有Script的reference对象数组。 4 var _references; 5 // 所有Script加载完之后执行的回调函数。 6 var _completionCallback; 7 // 执行回调函数时提供的上下文(参数)。 8 var _callbackContext; 9 10 // 当前正在加载的Script的HTTP Element(<script />)。 11 var _currentLoadingReference; 12 // 当前的Script加载完成后所调用的回调函数。 13 var _currentOnScriptLoad; 14 15 // ScriptLoader唯一的方法,传入三个参数,参数含义不再赘述。 16 this.load = function(references, completionCallback, callbackContext) { 17 _references = references; 18 _completionCallback = completionCallback; 19 _callbackContext = callbackContext; 20 21 loadReferences(); 22 } 23 24 // 开始加载引用。 25 function loadReferences() { 26 // 如果当前正在加载某个Script。 27 // 这表示此方法不是第一次被调用,而是在某个Script被加载 28 // 完成后才被调用,用以加载下一个Script。 29 if (_currentLoadingReference) { 30 // 查看当前Script元素的readyState,IE下为complete, 31 // 其他浏览器如FF则为loaded(FF其实并无此属性, 32 // 但是下面的代码会将其设为loaded)。 33 // 如果加载失败,则退出。 34 if ((_currentLoadingReference.readyState != 'loaded') && 35 (_currentLoadingReference.readyState != 'complete')) { 36 return; 37 } 38 else { 39 // 进入此分支,表明加载成功。 40 41 // 如果当前Script定义了onLoad函数。 42 if (_currentOnScriptLoad) { 43 // 通过eval调用(这里是个麻烦的地方)。 44 eval(_currentOnScriptLoad); 45 // 设为null,释放资源。 46 _currentOnScriptLoad = null; 47 } 48 49 // 将相关事件设为null以确保释放资源。 50 if (Sys.Runtime.get_hostType() != Sys.HostType.InternetExplorer) { 51 // 如果当前浏览器不是IE,见下面的代码 52 // 会发现为<script />定义了onload事件。 53 _currentLoadingReference.onload = null; 54 } 55 else { 56 // 如果是IE,见下面代码会发现为了 57 // <script />定义了onreadystatechange事件。 58 _currentLoadingReference.onreadystatechange = null; 59 } 60 61 // 最终释放当前的<script />引用。 62 _currentLoadingReference = null; 63 } 64 } 65 66 // 如果还有没有加载的Script。 67 if (_references.length) { 68 // 出队列。 69 var reference = _references.dequeue(); 70 // 创建<script /> 71 var scriptElement = document.createElement('script'); 72 // 设当前的<script />和当前加载成功的回调函数。 73 _currentLoadingReference = scriptElement; 74 _currentOnScriptLoad = reference.onscriptload; 75 76 if (Sys.Runtime.get_hostType() != Sys.HostType.InternetExplorer) { 77 // 如果不是IE的话,那么为<script />设属性readyState, 78 // 并且使用onload事件。 79 scriptElement.readyState = 'loaded'; 80 scriptElement.onload = loadReferences; 81 } 82 else { 83 // 如果是IE,那么使用onreadystatechange事件。 84 scriptElement.onreadystatechange = loadReferences; 85 } 86 scriptElement.type = 'text/javascript'; 87 scriptElement.src = reference.url; 88 89 // 将<script />添加至DOM 90 var headElement = document.getElementsByTagName('head')[0]; 91 headElement.appendChild(scriptElement); 92 93 return; 94 } 95 96 // 如果执行到这里,说明所有的Script已经加载完了。 97 // 如果定义了所有Script加载完之后执行的回调函数, 98 // 那么执行并释放资源。 99 if (_completionCallback) { 100 var completionCallback = _completionCallback; 101 var callbackContext = _callbackContext; 102 103 _completionCallback = null; 104 _callbackContext = null; 105 106 completionCallback(callbackContext); 107 } 108 109 _references = null; 110 } 111} 112Sys.ScriptLoader.registerClass('Sys.ScriptLoader');
0
相关文章