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>







18 comentários
Feed de comentários deste artigo
15 setembro 2007 às 13:51
Eduardo Habkost
Fiquei curioso: que padrão do W3C recomenda incluir os scripts entre as tags head?
15 setembro 2007 às 21:55
Mailson
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.
16 setembro 2007 às 21:30
Masaru Hoshi
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
16 setembro 2007 às 21:52
Eduardo Habkost
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.
17 setembro 2007 às 11:24
Alexandro
Muito boa esta dica!!
18 setembro 2007 às 14:20
Willian Fernandes
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,
19 setembro 2007 às 14:20
Chan
Bem não conhecia o atributo….
Teste aqui e não funcionou….. nem no IE nem no FF
Alguém ae testou ????
27 setembro 2007 às 19:23
Karlisson
Não tenho certeza, mas esse atributo não funciona no FF nem no Opera.
3 outubro 2007 às 18:54
Eric
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…
19 outubro 2007 às 21:18
Anonimo
Testei e não funcionou no FF.
25 outubro 2007 às 13:47
matheuseduardo
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!
4 dezembro 2007 às 17:28
rascunho » Blog Archive » links for 2007-12-04
[...] javascript-executando-scripts-apos-o-carregamento-da-pagina (tags: codare.net 2007 mes11 dia4 at_tecp javascript defer window_onload) [...]
13 janeiro 2008 às 1:41
Felipe Uchôa
Olá! Obrigado! Funcionou aqui, nos IE’s antigos! Obrigado!
25 setembro 2009 às 12:55
InvestMax
simples e funcional,
resolveu numa boa. Como o problema era só no ie mesmo, resolveu
grato
25 fevereiro 2010 às 8:59
Trudelmer
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.
31 março 2010 às 14:38
adorilson
Só funciona no IE, mesmo: http://www.w3schools.com/tags/att_script_defer.asp
Ou sejam, não usem. ;)
5 maio 2010 às 16:24
Osny Santos Netto
Not work in FF: http://developer.yahoo.com/performance/rules.html#js_bottom
4 julho 2010 às 11:16
Rodrigo Scrideli de Oliveira
Se for fugir dos padrões da W3C, acho melhor mesmo continuar entre a tag head os códigos JS