terça-feira, 30 de outubro de 2012

[JavaScript] Scripts Dinâmicos

[JavaScript] Scripts Dinâmicos.

Com conhecimentos de DOM (Document Object Model) você pode criar praticamente qualquer parte do seu HTML dinamicamente, usando apenas JavaScript. O elemento <script> não é diferente. Referências podem ser recuperadas do DOM, modificadas, removidas ou até mesmo criadas. Um novo elemento <script> pode ser facilmente criado usando métodos do DOM da seguinte forma:

var script = document.createElement("script");
script.type = "text/javascript"; //desnecessario no HTML5
script.src = arquivo1.js;
document.getElementsByTagName("head")[0].appendChild(script);

Este novo elemento <script> carrega o arquivo arquivo1.js. O arquivo começa a ser transferido para o browser tão logo o elemento seja adicionado na página. Vale lembrar que a interpretação do HTML é interrompida cada vez que um elemento <script> é encontrado e retomada após a execução do código em <script>.

O interessante nesta técnica, é que o arquivo é transferido e executado sem bloquear outros processos na página, não importando onde o download tenha sido iniciado. Você pode colocar este código no <head> do documento sem afetar o resto da página.

OBS: Trataremos do melhor lugar para colocar o <script> no próximo post. Por enquanto, é mais seguro colocá-lo no <head> e não no <body>, especialmente se tratamos de um elemento <script> executado durante o carregamento da página. No IE, se o <script> estiver no <body> é possível receber um erro do tipo "operation aborted" se todo o conteúdo do <body> não estiver completamente carregado.

Quando um arquivo é carregado pela criação dinâmica de um nó <script> no DOM, o código transferido, geralmente, é executado imediatamente (ressalvas para o Firefox e Opera, que irão aguardar até que <script>'s anteriores sejam executados.

Isto funciona bem com scripts auto suficientes (sefl-executing), mas podem ser problemáticos se o código contém interfaces para serem usadas por outros scripts na página. Neste caso você precisa rastrear quando o código foi completamente carregado e está disponível para uso. Se não estiver utilizando JQuery, teremos que fazê-lo pelos eventos que podem ser disparados pelo <script>.

Firefox, Opera, Chrome e Safari 3+ disparam um load quando o src de um <script> for recuperado. Você pode programar uma notificação, atribuindo a este evento uma função anônima para ficar ouvindo-o:

var script = document.createElement("script");
script.type = "text/javascript";

//Firefox, Opera, Chrome, Safari 3+
script.onload = function(){
    alert("Script carregado!");
};

script.src = "arquivo1.js";
document.getElementsByTagName("head")[0].appendChild(script);

No IE, bom... no caso do IE, pra variar, é diferente. Este navegador suporta uma implementação alternativa que dispara um evento readystatechange. Existe uma propriedade readyState no <script> que é carregada várias vezes durante a transferência do arquivo referenciado em seu src. Existem cinco possíveis valores para esta propriedade, são eles:

  • uninitialized, que é o default.
  • loading, quando o download do arquivo começa.
  • loaded, quando o download do arquivo termina.
  • interactive, quando os dados já foram baixados mas ainda não estão completamente disponíveis.
  • complete, quando os dados baixados estão prontos para serem utilizados.

O IE mostra-se inconsistente com os valores loaded e complete. Por vezes ele irá atingir o estado loaded e vai parar, sem disparar o complete. Calma que ainda pode piorar: outras vezes ele vai atingir o complete sem passar pelo loaded.

Sendo assim, é preciso tratar os dois estados relevantes para o carregamento loaded e complete, removendo o event handler (a função anônima atribuída ao evento) quando qualquer um deles ocorrer, para evitar de tratarmos duas vezes a mesma coisa (Ê laiá):

var script = document.createElement("script);
script.type = "text/javascript";

//Internet Explorer
script.onreadystatechange = function(){
    if(script.readyState == "loaded" || script.readyState == "complete"){
        script.onreadystatechange = null; //remove o event handler
        alert("Script carregado, eu acho!");
    }
};

Espero que os conhecimentos deste post lhe sejam úteis. No próximo post veremos o melhor lugar para colocar nossos scripts na página. Forte abraço.

Fonte: High Performance Javascript (Build Faster Web Application Interfaces) - Kindle Version, Location 603. Adaptações e sarcasmos de Mauricio da Silva Marinho.

Nenhum comentário: