tadarank afiliados

16 dezembro, 2006

Include em JavaScript

Olá povo.

Uma coisa de JavaScript um pouco incomum, que aparentemente ninguém possa ter precisado, mas que deve fazer muita falta para programadores que vêm de outras linguagens: um include em JavaScript.

"Bah, que isso mico, é só eu escrever a tag script e dizer o arquivo que quero chamar no head do HTML".

Sim, malandro, mas se você tiver vários arquivos javascript e não quiser incluir todos de uma vez?
Se você precisar incluir algum só se alguma determinada condição for feita?

Por exemplo

if(sou_bonito==true)  {
 include("chama_mulher.js");
} else if(tenho_grana==true) {
 include("chama_mais_mulher.js");
}else if(sou_inteligente==true){
 include("vai_trabalhar_vagabundo.js");
}

"Perae macaco doido. Comé que você vai fazer isso com JavaScript?"

Elementer meu caro leitor:

function include(arquivo){
//By Fabrício Magri e Micox
//http://elmicox.blogspot.com/2006/12/include-em-javascript.html
 var novo = document.createElement('script');
 novo.setAttribute('type', 'text/javascript');
 novo.setAttribute('src', arquivo);
 document.getElementsByTagName('head')[0].appendChild(novo);
 //apos a linha acima o navegador inicia o carregamento do arquivo
 //portanto aguarde um pouco até o navegador baixá-lo. :)
}

Infelizmente, pra variar, o meu Opera 8.5 não gostou deste script. Mas é a vida... No IE 6.0 e no FF 2.0 deu tudo beleza.
Graças ao comentário de um anônimo Fabrício Magri o script funfou no Opera 8.5 (vejam os comentários), muito obrigado :). Agora funciona corretamente no FF, IE e OP.

Bugs, dúvidas, sugestões é só comentar aí. Comenta pra eu escrever mais.

Amanhã tem mais postagem. Agora tô com pressa. Até lá.

Gostou da dica acima? Então clica nos botões de compartilhamento abaixo e me ajude a dica a subir no Google.

28 comentários:

  1. Olá, não sei se isso funcionaria corretamente em 100% dos casos. Não sei se ao criar o elemento ele pula para a próxima execução do JS, ou se ele espera que o arquivo seja 100% carregado para ir para a próxima instrução.

    Se o primeiro caso for verdadeiro, pode ocorrer erro de js (uma função que ainda não foi declarada).

    Vale a pena fazer mais testes... Porém é uma boa dica.

    ResponderExcluir
  2. Umm, é verdade gustavo. VAleu pelo lembrete.
    Realmente acho que não executará coisas em sequencia já que insere um novo objeto NO HTML e não no javascript.
    Mas ainda assim creio que valha para funções, frameworks, etc.
    Valeu ae.

    ResponderExcluir
  3. Muito bom!
    Me lembro as coisas locas que eu às vezes faço para cobrir funções do PHP, como meu isset() que criei... hehehe Flwss...

    ResponderExcluir
  4. Bem interessante, não sabia que dava pra fazer isso com JavaScript!!!

    ResponderExcluir
  5. entao cara,
    na realidade, voce deve incluir o arquivo.js nas tags head certo !?
    e outra, com esse script que voce, é possivel incluir um arquivo várias vezes !!

    ResponderExcluir
  6. Ué Anônimo. Não entendi.

    Sim, eu posso carregar o script como um filho do head ao invés de um filho do body.

    Sim, é possível incluir um arquivo várias vezes. Só que não terá efeito prático pois as funções de dentro deste arquivo serão as mesmas.

    Qualquer coisa explica melhor ae.

    ResponderExcluir
  7. Fala Mico, maneiro o texto.
    Cara eu já tive problemas tentando fazer isso com DOM e por isso, costumo usar assim:

    function include(src) {
    document.write('<scr'+'ipt type="text/javascript" language="Javascript" src="'+file+'"></scr'+'ipt>\n');
    }

    O mal é que nesse esquema, com document.write, só funciona no onload...

    ResponderExcluir
  8. Buenas... Nestes casos gosto de me basear em "grandes" criações. Logo quando comecei a ler o post lembrei da scriptaculous, jah havia visto algo semelhante nos codigos dela. Agora que vi toda esta discução nos comentarios resolvi olhar os fontes dela novamente. Achei o seguinte:

    require: function(libraryName) {
    // inserting via DOM fails in Safari 2.0, so brute force approach
    document.write('*script type="text/javascript" src="'+libraryName+'">*/script>');
    },

    Já tem até um comentário que facilita as coisas... flw

    ResponderExcluir
  9. Olá,
    tente escrever o código assim que eu acredito que vai funcionar no opera 8.5 sem problemas.
    Tirando os casos do IE, os codigos não funcionam no opera ou no FF por não estarem bem escritos.

    function include(arquivo){
    //By Micox - http://elmicox.blogspot.com
    var novo = document.createElement('script');
    novo.setAttribute('type', 'text/javascript');
    novo.setAttribute('src', arquivo);
    document.getElementsByTagName('body')[0].appendChild(novo);
    //apos a linha acima o navegador inicia o carregamento do arquivo
    //portanto aguarde um pouco até o navegador baixá-lo. :)
    }

    ResponderExcluir
  10. Um detalhe que ainda ficou errado...

    é adicionado no head e não no body...

    document.getElementsByTagName('head')[0].appendChild(novo);

    ResponderExcluir
  11. Opa Anônimo, valeus.

    Seu código funfou no Opera, vou adicionar lá e incluir seu nome (anônimo).

    Só que eu deverei adicionar no body pra funcionar no Opera 8.5, senão não funfa.

    ResponderExcluir
  12. Estranho Micox, funciona no elemento head sim no opera. Eu fiz um teste e funcionou...

    Outra coisa, vc usa <> no createElement:
    document.createElement("<script>");

    Sempre usei só o nome:
    document.createElement("script");
    e nunca tinha visto usar assim com <>, não sei se isso pode estar influenciando em não funcionar no head no opera 8.5

    Falou,

    * Excelente blog!!! E meu nome é Fabrício Magri

    ResponderExcluir
  13. Opa. Valeu Fabrício (o cara do PHP hehe).
    Script corrigido, era uma falha minha na digitação mesmo (mico burro hehe).

    Créditos e link incluido. Qualquer coisa é só falar que eu altero.

    ResponderExcluir
  14. gustavo e micox... eu tentei adicionar um js de 500 kb e tive problemas no IE. Pelo que vi, ele cria o objeto, mas não espera pelo download do arquivo para continuar a execução do script. No Firefox funciona perfeitamente.

    ResponderExcluir
  15. Ummm, é verdade Marcio.
    Acho que é possível fazer algumas implementações pra melhorar isso aí usando o 'onready' ou o 'onload'.

    Quando eu tiver um tempo dou uma arrumada.

    Valeus.

    ResponderExcluir
  16. onready? naum conheço esse evento... como ele funciona?

    ResponderExcluir
  17. micox, usei a sua dica para o IE. Notei q na primeira execução, o estado final não é 'complete', mas sim 'loaded'. No meu caso, foi preciso ler novamente a página (document.location.reload() não funcionou) para executar a minha função, mas com scripts mais simples basta um if com js.readyState=='complete' || js.readyState=='loaded'. Abaixo está o meu código

    js.onreadystatechange = function () {
    if (js.readyState=='complete') {
    execute();
    } else if (js.readyState=='loaded') {
    document.location='/';
    }
    }

    ResponderExcluir
  18. Ok. Obrigado pela contribuição Marcio.
    Em breve implemento isto em minha função.
    Obrigado.

    ResponderExcluir
  19. micox, ainda não pude testar essa condição, mas o que acontece se houver problemas com a conexão durante o download do arquivo?

    ResponderExcluir
  20. O arquivo não será carregado, porém minha função não avisará nada :(

    Então nos scripts que se seguirem, caso eles façam chamada a alguma função que tinha no arquivo que deveria carregar irá dar erro.

    ResponderExcluir
  21. micox, eu testei essa condição, e é isso mesmo que acontece...
    é possível fazer um tratamento com o onerror, o problema é que o Firefox dispara tal evento, mas o IE não. Sabe de algum equivalente para o internet explorer?

    ResponderExcluir
  22. Ixx cara, então complicou.
    O equivalente ao onerror no IE é onerror mesmo.
    Mas testar o onstatechange não dá nada quando dá o erro não?

    ResponderExcluir
  23. entaum... o onerror só não é implementado no script. Para outras tags como img, ele é disparado sim.

    ResponderExcluir
  24. Bom márcio, então vc pode tentar usar o Try-catch no javascript também.

    ResponderExcluir
  25. Galera, só um detalhe, o include do php, por exemplo, executa tanto as funcões php como também exibe o html normalmente. Era isso que eu queria com o javascript, pois a única maneira de mostrar o html é usando document.write ou innerHTML em cada linha. Pó, cada linha é canseira, já pensou? Se as variáveis recebessem o valor até o fechamento das aspas e ponto-virgula seria ótimo, mas na quebra de linha da erro. A solução seria colocar tudo numa linha, sem quebra, mas também não é viável. Alguém pode ajudar?

    ResponderExcluir
  26. Vocês já testaram para ver se funciona no Google Chrome??

    ResponderExcluir
  27. Ainda não cara. Na época que foi feito não tinha Chrome.
    Testa aí e volta pra comentar pra gente. Valeus.

    ResponderExcluir

Resultado! Concursos