Кто-то спросил меня сегодня, как реализовать индикатор выполнения загрузки Javascript, например, почтовый ящик 163.
Не знаю, но реализовать его несложно, потому что в есть onload и onreadystatechange. Также у нас есть Атлас.
В Atlas есть класс: Sys.ScriptLoader, его функция — последовательно загружать на страницу несколько файлов сценариев. Прежде чем реализовать, давайте проанализируем код этого класса.
1Sys.ScriptLoader = функция() {
2
3 //Массив ссылочных объектов для всех скриптов.
4 вар _references;
5 //Функция обратного вызова, выполняемая после загрузки всех скриптов.
6 вар _completionCallback;
7 // Контекст (параметры), предоставляемый при выполнении функции обратного вызова.
8 вар _callbackContext;
9
10 // HTTP-элемент () загружаемого в данный момент скрипта.
11 вар _currentLoadingReference;
12 // Функция обратного вызова, вызываемая после загрузки текущего скрипта.
13 вар _currentOnScriptLoad;
14
15 // Единственный метод ScriptLoader — передать три параметра. Значение параметров не будет повторяться.
16 this.load = функция (ссылки, завершениеCallback, callbackContext) {
17 _references = ссылки;
18 _completionCallback = завершениеCallback;
19 _callbackContext = callbackContext;
20
21 ЗагрузитьСсылки();
двадцать два }
двадцать три
24 // Начинаем загрузку ссылок.
25 функция loadReferences() {
26 // Если в данный момент загружается скрипт.
27 // Это означает, что этот метод не вызывается в первый раз, а загружается в скрипт
28 // Вызывается после завершения для загрузки следующего скрипта.
29, если (_currentLoadingReference) {
30 // Проверяем ReadyState текущего элемента Script, который завершен в IE.
31 // Другие браузеры, такие как FF, загружаются (у FF на самом деле нет этого атрибута.
32 // Но код ниже установит его как загруженный).
33 // Если загрузка не удалась, выходим.
34 if ((_currentLoadingReference.readyState != 'загружено') &&
35 (_currentLoadingReference.readyState != 'завершено')) {
36 возврат;
37 }
38 еще {
39 // Вход в эту ветку означает успешную загрузку.
40
41 // Если текущий скрипт определяет функцию onLoad.
42, если (_currentOnScriptLoad) {
43 // Вызывается через eval (вот в чем проблема).
44 eval(_currentOnScriptLoad);
45 //Установите значение null, чтобы освободить ресурсы.
46 _currentOnScriptLoad = ноль;
47 }
48
49 // Установите для связанных событий значение null, чтобы гарантировать освобождение ресурсов.
50 if (Sys.Runtime.get_hostType() != Sys.HostType.InternetExplorer) {
51 // Если текущий браузер не IE, см. код ниже
52 // Вы обнаружите, что событие загрузки определено для .
53 _currentLoadingReference.onload = ноль;
54 }
55 еще {
56 // Если это IE, посмотрите код ниже, и вы обнаружите, что
57 // определяет событие onreadystatechange.
58 _currentLoadingReference.onreadystatechange = ноль;
59 }
60
61 //Наконец освобождаем текущую ссылку .
62 _currentLoadingReference = ноль;
63}
64}
65
66 // Если еще есть незагруженные скрипты.
67, если (_references.length) {
68 // Удаление из очереди.
69 var ссылка = _references.dequeue();
70 // Создать <скрипт />
71 var scriptElement = document.createElement('script');
72 //Устанавливаем текущий и текущую функцию обратного вызова для успешной загрузки.
73 _currentLoadingReference = scriptElement;
74 _currentOnScriptLoad = reference.onscriptload;
75
76 if (Sys.Runtime.get_hostType() != Sys.HostType.InternetExplorer) {
77 // Если это не IE, то установите атрибут ReadyState для .
78 // И используем событие загрузки.
79 scriptElement.readyState = 'загружено';
80 scriptElement.onload = loadReferences;
81 }
82 еще {
83 // Если это IE, используйте событие onreadystatechange.
84 scriptElement.onreadystatechange = loadReferences;
85}
86 scriptElement.type = 'текст/javascript';
87 scriptElement.src = reference.url;
88
89 // Добавляем в DOM
90 var headElement = document.getElementsByTagName('head')[0];
91 headElement.appendChild(scriptElement);
92
93 возврата;
94}
95
96 // Если выполнение доходит до этой точки, это означает, что все скрипты загружены.
97 // Если определена функция обратного вызова, которая выполняется после загрузки всех сценариев,
98 // Затем выполняем и освобождаем ресурсы.
99 если (_completionCallback) {
100 вар завершениеCallback = _completionCallback;
101 вар callbackContext = _callbackContext;
102
103 _completionCallback = ноль;
104 _callbackContext = ноль;
105
106 завершениеCallback(callbackContext);
107 }
108
109 _references = ноль;
110 }
111}
112Sys.ScriptLoader.registerClass('Sys.ScriptLoader');
Видно, что метод Sys.ScriptLoader для загрузки сценария заключается в последовательном добавлении элементов в
На самом деле код Sys.ScriptLoader очень простой, и добавленные мной комментарии кажутся лишними. Стоит отметить, что все ресурсы высвобождаются максимально. Обратите особое внимание на код, начинающийся со строки 99. Тело if сначала использует временные переменные для сохранения двух глобальных переменных, а затем освобождает глобальные переменные. Его цель — избежать утечек памяти, вызванных исключениями, возникающими при выполнении завершенияCallback, даже если такая возможность существует только одна из десяти тысяч. Чем больше Javascript, тем легче вызвать утечки памяти. Лучше всего обратить внимание на эту проблему при написании JS-кода.
Далее объясните первый параметр метода загрузки — ссылки. Первоначально я думал, что это массив класса Sys.Reference, но обнаружил, что на самом деле это совсем другое. В любом случае, взгляните на код этого класса.
1Sys.Reference = функция() {
2
3 вар _компонент;
4 вар _onload;
5
6 this.get_comComponent = function() {
7 вернуть _компонент;
8}
9 this.set_comComponent = функция (значение) {
10 _компонент = значение;
11 }
12
13 this.get_onscriptload = function() {
14 возврат _onload;
15}
16 this.set_onscriptload = функция(значение) {
17 _onload = значение;
18}
19
20 this.dispose = function() {
21 _компонент = ноль;
двадцать два }
двадцать три
24 this.getDescriptor = function() {
25 var td = новый Sys.TypeDescriptor();
26
27 td.addProperty('компонент', Объект);
28 td.addProperty('onscriptload', String);
29 возвращение тд;
30}
31}
32Sys.Reference.registerSealedClass('Sys.Reference', null, Sys.ITypeDescriptorProvider, Sys.IDisposable);
33Sys.TypeDescriptor.addType('скрипт', 'ссылка', Sys.Reference);
Обратив внимание на код класса Sys.ScriptLoader, мы видим, что каждый элемент ссылочного массива на самом деле представляет собой простой "{ url: " http://www.sample.com/sample.js ", onscriptload: " alert(1)"}" объект формы. Но это нормально, вы можете легко использовать JSON для создания такого массива.
На этом этапе, я думаю, каждый должен был подумать о том, как использовать Sys.ScriptLoader, чтобы легко создать индикатор выполнения загрузки JS. Но теперь, когда я написал это здесь, я продолжу реализовывать это простым способом.
Во-первых, это файл aspx.
1<%@ Язык страницы="C#" %>
2
3http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
4
5