Javascript: Executando scripts após o carregamento da página

Palavras-chave: DEFER, onLoad, body, carregamento

O problema é clássico. Você tem uma função/método e deseja que ele seja chamado apenas após o carregamento da página pois esse script interage com algum elemento da página que precisa estar completamente renderizado para poder ser manipulado. Vejamos o exemplo a seguir que muda um objeto do tipo input text para apenas leitura:

<html>
<head>
<script type="text/javascript">
function setDisabled() {
  document.getElementById("foo").disabled = true;
}
// Chamada da função
setDisabled();
</script>
</head>
  <body>
    <form method="post">
      <input type="text" name="foo" id="foo" size="20">
      <input type="submit">
    </form>
  </body>
</html>

Inicialmente esse exemplo deveria ser o suficiente para funcionar. Contudo, não podemos considerar que toda a página será carregada de uma única vez. Caso isso aconteça, quando a função for chamada campo o input pode não ter sido carregado. Resultado: você terá um erro de script.

Existem várias saídas para esse tipo de situação. A mais conhecida é incluir a chamada da função pelo método onLoad da tag body ao invés de executá-lo dentro do bloco <script>:

<body onLoad="setDisabled()">

Mas pode não ser suficiente caso você tenha muitos mais funções a serem chamadas. Outra saída seria incluir o bloco <script> no final do código, mas isso foge um pouco do padrão do W3C de incluir todos os <scripts> entre as tags <head>. A saída para esse problema é a utilização de um atributo pouco conhecido da tag <script>, o DEFER.

O DEFER indica que o bloco script só será carregado após todo o carregamento da página. Dessa forma, para que o primeiro exemplo apresentado funcione bastaria alterá-lo para incluir o atributo:

<script type="text/javascript" DEFER="DEFER">
function setDisabled() {
  document.getElementById("foo").disabled = true;
}

// Chamada da função
setDisabled();
</script>
This entry was posted in JavaScript. Bookmark the permalink.

19 Responses to Javascript: Executando scripts após o carregamento da página

  1. Fiquei curioso: que padrão do W3C recomenda incluir os scripts entre as tags head?

  2. Mailson says:

    Bastante interessante isso e muito melhor que colocar a definição do script no final da página. Principalmente se você costuma separar o Java Script do código.

  3. Masaru Hoshi says:

    Olá Eduardo.

    Pelo menos é o que eu entendi até hoje. Pelo que pude ler na especificação do HTML 4.01, o W3C recomenda que, caso seja necessário incluir tags <SCRIPT> que elas sejam incluídas como nodos filhos do HEAD.

    http://www.w3.org/TR/html401/struct/global.html#h-7.4

  4. Não consegui encontrar na especificação onde está a recomendação de que os scripts estejam no head e não no body.

    Vi que o body também pode ter tags script dentro dele (http://www.w3.org/TR/html401/struct/global.html#h-7.5.1). Só não encontrei nada que recomendasse usar o head e não o body, ou que comparasse as duas possibilidades.

  5. Alexandro says:

    Muito boa esta dica!!

  6. Pessoal,
    não é mais recomendado utilizar o atributo onload da tag body. Para realmente funcionar, façam assim (em qualquer lugar da página).

    window.onload = function () {
    nomeDaFuncao1();
    nomeDaFuncao2();
    nomeDaFuncao3();
    }

    Ow, se quiser melhorar mais ainda utilizar a função addEvent (http://www.metzen.com.br/freedom/):
    addEvent(window, “load”, “nomeDaFuncao1″);
    addEvent(window, “load”, “nomeDaFuncao2″);
    addEvent(window, “load”, “nomeDaFuncao3″);

    E lembre-se, todos os nomes de atributos de tags devem ser escritos em minúsculo:
    onClick = ERRADO
    onclick = CORRETO

    Abraços,

  7. Chan says:

    Bem não conhecia o atributo….
    Teste aqui e não funcionou….. nem no IE nem no FF
    Alguém ae testou ????

  8. Karlisson says:

    Não tenho certeza, mas esse atributo não funciona no FF nem no Opera.

  9. Eric says:

    O Dreamweaver ‘conhece’ o atributo, mas parece que não funciona não…

    Tentei usar no meu problema mas não mudou nada…

    Depois farei uns testes isolados pra ver qual é a dessa defer…

  10. Anonimo says:

    Testei e não funcionou no FF.

  11. Esse atributo (infelizmente) só funciona no Internet ExploDer!.. Digo.. não funciona no FF… e acho q no Safari também não.

    Há poucos dei uma pesquisada na internet… Tem até uma página que verifica, mostrando a ordem de execução com scripts em vários locais.

    Abraço!

  12. Pingback: rascunho » Blog Archive » links for 2007-12-04

  13. Olá! Obrigado! Funcionou aqui, nos IE’s antigos! Obrigado!

  14. InvestMax says:

    simples e funcional,
    resolveu numa boa. Como o problema era só no ie mesmo, resolveu
    grato

  15. Trudelmer says:

    Olá a todos, estou com o seguinte problema:
    Tenho um function teste(texto)
    {alert(texto);return true;} dentro de uma arquivo carregado
    na página via ajax, no fim desse mesmo arquivo eu tenho AQUI mas isso não funciona. Ao clicar
    da o seguinte erro (firebug) “teste is not defined”, isso é evidente,
    o objeto chamado não existe, so funciona se eu colocar no ,
    existe solução para isso? ou seja, é possível manter um
    dentro de um arquivo carregado via ajax e “??declarar ou definir??”
    ele (seus objetos) para que fique disponível para toda a página? Já
    procurei de tudo na internet e já testei muita coisa mas nada
    funcionou.

  16. adorilson says:

    Só funciona no IE, mesmo: http://www.w3schools.com/tags/att_script_defer.asp

    Ou sejam, não usem. ;)

  17. Se for fugir dos padrões da W3C, acho melhor mesmo continuar entre a tag head os códigos JS

  18. Claiton says:

    Só para constar. A recomendação colocar Javascript dentro da tag é antiga mas ainda é valida. O motivo é que em navegadores sem suporte a Javascript o código apareceria na tela.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>