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>