Alguém me perguntou hoje como implementar uma barra de progresso de carregamento de Javascript como a caixa de correio 163.
Não sei, mas não é difícil implementar um, pois possui onload e onreadystatechange. Além disso, temos Atlas.
Existe uma classe no Atlas: Sys.ScriptLoader, sua função é carregar vários arquivos Script na página em sequência. Antes de implementá-lo, vamos analisar o código desta classe.
1Sys.ScriptLoader = função() {
2
3 //Array de objetos de referência para todos os Scripts.
4 var _referências;
5 //Função de callback executada após todos os Scripts serem carregados.
6 var _completionCallback;
7 // O contexto (parâmetros) fornecido ao executar a função de retorno de chamada.
8 var _callbackContext;
9
10 // Elemento HTTP () do Script atualmente carregado.
11 var _currentLoadingReference;
12 // A função de retorno de chamada chamada após o script atual ser carregado.
13 var _currentOnScriptLoad;
14
15 // O único método do ScriptLoader é passar três parâmetros. O significado dos parâmetros não será repetido.
16 this.load = função (referências, conclusãoCallback, callbackContext) {
17 _referências = referências;
18 _completionCallback = completeCallback;
19 _callbackContext = callbackContext;
20
21 loadReferences();
vinte e dois }
vinte e três
24 // Começa a carregar referências.
25 função loadReferences() {
26 // Se um Script está sendo carregado no momento.
27 // Isso significa que este método não é chamado pela primeira vez, mas é carregado em um Script
28 // Chamado após a conclusão para carregar o próximo Script.
29 se (_currentLoadingReference) {
30 // Verifica o readyState do elemento Script atual, que está completo no IE.
31 // Outros navegadores como o FF são carregados (o FF na verdade não possui esse atributo.
32 // Mas o código abaixo irá configurá-lo para carregado).
33 // Se o carregamento falhar, saia.
34 if ((_currentLoadingReference.readyState! = 'carregado') &&
35 (_currentLoadingReference.readyState! = 'completo')) {
36 retorno;
37}
38 mais {
39 // Entrar neste branch indica carregamento bem-sucedido.
40
41 // Se o Script atual define a função onLoad.
42 se (_currentOnScriptLoad) {
43 // Chamado via eval (aqui está o problema).
44 avaliação(_currentOnScriptLoad);
45 //Definido como nulo para liberar recursos.
46 _currentOnScriptLoad = nulo;
47}
48
49 // Defina eventos relacionados como nulos para garantir que os recursos sejam liberados.
50 se (Sys.Runtime.get_hostType()! = Sys.HostType.InternetExplorer) {
51 // Se o navegador atual não for IE, veja o código abaixo
52 // Você descobrirá que o evento onload está definido para .
53 _currentLoadingReference.onload = null;
54}
55 mais {
56 // Se for IE, veja o código abaixo e você descobrirá que
57 // define o evento onreadystatechange.
58 _currentLoadingReference.onreadystatechange = null;
59}
60
61 //Finalmente libera a referência atual.
62 _currentLoadingReference = nulo;
63}
64}
65
66 // Se ainda houver Scripts descarregados.
67 if (_referências.length) {
68 // Desfilar.
69 var referência = _references.dequeue();
70 // Cria
71 var scriptElement = document.createElement('script');
72 //Defina o atual e a função de retorno de chamada atual para carregamento bem-sucedido.
73 _currentLoadingReference = scriptElement;
74 _currentOnScriptLoad = referência.onscriptload;
75
76 se (Sys.Runtime.get_hostType()! = Sys.HostType.InternetExplorer) {
77 // Se não for IE, então defina o atributo readyState para .
78 // E use o evento onload.
79 scriptElement.readyState = 'carregado';
80 scriptElement.onload = loadReferences;
81}
82 mais {
83 // Se for IE, use o evento onreadystatechange.
84 scriptElement.onreadystatechange = loadReferences;
85}
86 scriptElement.type = 'texto/javascript';
87 scriptElement.src = referência.url;
88
89 // Adicione ao DOM
90 var headElement = document.getElementsByTagName('head')[0];
91 headElement.appendChild(scriptElement);
92
93 retorno;
94}
95
96 // Se a execução chegar a este ponto, significa que todos os scripts foram carregados.
97 // Se a função de retorno de chamada que é executada após o carregamento de todos os Scripts for definida,
98 // Em seguida, execute e libere recursos.
99 se (_completionCallback) {
100 var conclusãoCallback = _completionCallback;
101 var callbackContext = _callbackContext;
102
103 _completionCallback = null;
104 _callbackContext=nulo;
105
106 conclusãoCallback(callbackContext);
107}
108
109 _referências = nulo;
110}
111}
112Sys.ScriptLoader.registerClass('Sys.ScriptLoader');
Pode-se observar que o método para Sys.ScriptLoader carregar o script é adicionar elementos a
Na verdade, o código do Sys.ScriptLoader é muito simples e os comentários que adicionei parecem supérfluos. Vale ressaltar que todos os recursos são liberados na medida do possível. Preste atenção especial ao código a partir da linha 99. O corpo if primeiro usa variáveis temporárias para reter duas variáveis globais e depois libera as variáveis globais. Seu objetivo é evitar vazamentos de memória causados por exceções lançadas quando o completeCallback é executado, mesmo que haja apenas uma possibilidade em dez mil. Quanto mais Javascript houver, mais fácil será causar vazamentos de memória. É melhor prestar atenção a esse problema ao escrever código JS.
A seguir, explique o primeiro parâmetro do método de carregamento, referências. Originalmente pensei que fosse um array da classe Sys.Reference, mas descobri que na verdade era bem diferente. De qualquer forma, dê uma olhada no código desta classe.
1Sys.Referência = função() {
2
3 var _componente;
4 var _onload;
5
6 this.get_component = function() {
7 retornar _componente;
8}
9 this.set_component = função (valor) {
10 _componente = valor;
11}
12
13 this.get_onscriptload = function() {
14 return _onload;
15}
16 this.set_onscriptload = função (valor) {
17 _onload = valor;
18}
19
20 this.dispose = function() {
21 _componente = nulo;
vinte e dois }
vinte e três
24 this.getDescriptor = function() {
25 var td = new Sys.TypeDescriptor();
26
27 td.addProperty('componente', Objeto);
28 td.addProperty('onscriptload', String);
29 retorno td;
30}
31}
32Sys.Reference.registerSealedClass('Sys.Reference', null, Sys.ITypeDescriptorProvider, Sys.IDisposable);
33Sys.TypeDescriptor.addType('script', 'referência', Sys.Reference);
Prestando atenção ao código da classe Sys.ScriptLoader, podemos ver que cada elemento do array de referência é na verdade apenas um simples "{url:" http://www.sample.com/sample.js ", onscriptload:" alert(1)"}" objeto de formulário. Mas tudo bem, você pode facilmente usar JSON para construir tal array.
Neste ponto, acho que todos deveriam ter pensado em como usar Sys.ScriptLoader para criar facilmente uma barra de progresso de carregamento JS. Mas agora que escrevi aqui, continuarei a implementá-lo de forma simples.
O primeiro é o arquivo aspx.
1<%@ Idioma da página="C#" %>
2
3http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
4
5
8
9http://www.w3.org/1999/xhtml " >
10