window.onload vs <body onload = "" />

227

Qual é exatamente a diferença entre o window.onloadevento e o onloadevento da bodytag? quando uso qual e como deve ser feito corretamente?

Manu
fonte
2
você deve usar "cercar o valor do atributo
Sven Larson

Respostas:

218

window.onload = myOnloadFunce <body onload="myOnloadFunc();">são diferentes maneiras de usar o mesmo evento . O uso window.onloadé menos invasivo - remove o JavaScript do HTML.

Todas as bibliotecas JavaScript comuns, Prototype, ExtJS, Dojo, JQuery, YUI, etc. fornecem wrappers agradáveis ​​em torno de eventos que ocorrem quando o documento é carregado. Você pode ouvir o evento onLoad da janela e reagir a isso, mas o onLoad não é acionado até que todos os recursos tenham sido baixados; portanto, seu manipulador de eventos não será executado até que a última imagem enorme seja obtida. Em alguns casos, é exatamente isso que você deseja; em outros, você pode achar que ouvir quando o DOM está pronto é mais apropriado - esse evento é semelhante ao onLoad, mas é acionado sem aguardar o download das imagens, etc.

Richard Turner
fonte
57
Note-se, no entanto, que há uma diferença. O evento on-line onload será chamado myOnloadFunc()no contexto global ( thisse referirá a window). A configuração via javascript fará com que seja executado no contexto do elemento ( thisrefere-se ao elemento no qual o evento foi disparado). Nesse caso em particular, não fará diferença, mas fará com outros elementos.
mowwwalker
1
@Walkerneo: Sim, definitivamente vale a pena notar. Obviamente, usando uma biblioteca JS, é possível substituir o objeto que thisse refere, se desejado.
Richard Turner
@RichardTurner Você não precisa usar uma biblioteca para alterar a ligação de contexto. Uma simples chamada .bind () faz isso
Kloar
@ Kloar você pode nos dias de hoje, sim, mas você precisa do MSIE9 +. No MSIE mais antigo, que era muito mais comum quando respondi, você precisaria de um polyfill.
Richard Turner
33

Não há diferença, mas você também não deve usar.

Em muitos navegadores, o window.onloadevento não é acionado até que todas as imagens sejam carregadas, o que não é o que você deseja. Navegadores baseados em padrões têm um evento chamado DOMContentLoadedque é disparado anteriormente, mas não é suportado pelo IE (no momento em que escrevemos esta resposta). Eu recomendo usar uma biblioteca javascript que ofereça suporte a um recurso DOMContentLoaded entre navegadores ou encontrar uma função bem escrita que você possa usar. jQuery $(document).ready(), é um bom exemplo.

jcampbell1
fonte
53
Pergunta do futuro ... E se não houver jquery?
Sid
54
Pergunta do presente .. E se o jQuery for um exagero para o projeto em questão? (Não bater jQuery, use-me apenas às vezes só querem uma característica fora de uma biblioteca ...)
Bradmage
14
Quando você diz "não suportado pelo IE", isso é uma verdade universal, ou apenas verdadeira para versões específicas do IE? Como muita coisa mudou no mundo dos navegadores desde que você escreveu esta resposta, talvez seja hora de atualizar essa resposta?
Bryan Oakley
8
O DOMContentLoaded agora é suportado pelo IE9 e acima: developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Adam
6
Relatórios do futuro, DOMContentLoaded agora é suportado por todos os principais navegadores: caniuse.com/#feat=domcontentloaded
José Gómez
21

window.onloadpode trabalhar sem corpo. Crie uma página apenas com as tags de script e abra-a em um navegador. A página não contém nenhum corpo, mas ainda funciona ..

<script>
  function testSp()
  {
    alert("hit");
  }
  window.onload=testSp;
</script>
john Joseph
fonte
6
O HTML sem a tag body é inválido se você realmente adicionar conteúdo (que deve estar em uma tag body). Também está faltando um tipo na sua tag de script. Nunca confie nos navegadores que corrigem seu código não compatível com os padrões! (Como os navegadores podem fazê-lo de maneira diferente ou nada diferente no passado ou no futuro.) #
Kissaki
4
@Kissaki: HTML padrão não precisa de uma etiqueta corporal!
Robert Siemer 29/05
5
xhtml1 especifica <!ELEMENT html (head, body)>[1] - e html401 especifica também <!ELEMENT HTML O O (%html.content;)com <!ENTITY % html.content "HEAD, BODY">[2]. O html51 também indica o A head element followed by a body element.conteúdo html. [3] w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict w3.org/TR/html51/semantics.html#the -html-element - Então eu acho que todos esses padrões HTML comum / em uso fazer exigem uma tag corpo. :)
Kissaki
1
@ Kissaki que é XHTML, não HTML. O HTML permite a omissão de tags de tags de corpo inicial e final, bem como a omissão de tags html e head, conforme sua SGML DTD. w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoded
1
@Kissaki: html5 não precisa mais do tipo de script (se for javascript), você está certo em versões anteriores.
Mark
10

Eu prefiro, geralmente, não usar o <body onload=""evento>. Eu acho que é mais limpo manter o comportamento separado do conteúdo, tanto quanto possível.

Dito isto, há ocasiões (geralmente bastante raras para mim) em que o uso da carga corporal pode dar um pequeno aumento de velocidade.

Eu gosto de usar o Prototype, então geralmente coloco algo assim <head> na minha página:

document.observe("dom:loaded", function(){
  alert('The DOM is loaded!');
});

ou

Event.observe(window, 'load', function(){
  alert('Window onload');
});

O acima são truques que aprendi aqui . Gosto muito do conceito de anexar manipuladores de eventos fora do HTML.

(Edite para corrigir o erro de ortografia no código.)

Mark Biek
fonte
Em que ocasiões seria mais rápido e por quê?
Kissaki
Essa resposta parece muito subjetiva com todos os "eu" ("eu prefiro", "eu acho"). Que, se ainda não possui fatos objetivos e verificáveis, apoia essa impressão.
Kissaki
1
Eu aceitaria essa resposta com um grão de sal, considerando que ela foi publicada há mais de 6 anos. Você pode atualizá-lo ou postar sua própria resposta aprimorada.
precisa saber é o seguinte
7

'tantas respostas subjetivas para uma pergunta objetiva. JavaScript "discreto" é uma superstição como a regra antiga de nunca usar gotos. Escreva o código de uma maneira que o ajude a atingir seu objetivo de maneira confiável, não de acordo com as crenças religiosas da moda de alguém.

Quem encontrar:

 <body onload="body_onload();">

distrair demais é excessivamente pretensioso e não tem suas prioridades em ordem.

Normalmente, coloco meu código JavaScript em um arquivo .js separado, mas não encontro nada complicado em conectar manipuladores de eventos em HTML, que é um HTML válido por sinal.


fonte
39
Há uma boa razão para escrever javascript discreto. Digamos que você tenha um aplicativo Web com 100 páginas e tenha usado o método <body onload = "body_onload ();"> em vez de colocá-lo no arquivo javascript incluído em todas as páginas. Imagine que você precisou alterar o nome dessa função por algum motivo. Colocar o evento no arquivo javascript incluído 1) torna as alterações muito mais simples e 2) economiza recursos do servidor, pois os arquivos javascript podem ser armazenados em cache por um ano (em um servidor configurado corretamente) em vez de baixar o mesmo código repetidamente.
Andrew Ensley
21
Então, porque você não se incomoda em aprender por que algo é recomendado, rotule as recomendações de "crenças religiosas da moda"?
hallvors
6
A pergunta é "qual é a diferença entre esses dois métodos?", Juntamente com uma solicitação de recomendação para qual é melhor. Como sua resposta responde a essa pergunta?
Richard Turner
1
Qualquer situação em que você faça uma solução modular em um local que possa ser aplicada a uma grande quantidade de arquivos é muito melhor do que adicionar o código a cada uma delas. É melhor para o tempo de criação original, propósitos organizacionais de código, legibilidade e edição futura. Não está na moda, na verdade é um conceito mais antigo que está presente em linguagens como java e c ++ que os programadores da web estão adotando como a maneira muito melhor de codificar.
perfil completo de Jimbo Jonny
1
Uma boa defesa contra ataques XSS nos navegadores modernos é desativar todo o javascript embutido com sua Política de Segurança de Conteúdo. Essa é uma boa razão para não usar o atributo onload no seu HTML.
Greg Bola
4

window.onload- Chamado após todos os arquivos DOM, JS, imagens, iframes, extensões e outros completamente carregados. Isso é igual a $ (window) .load (function () {});

body onload=""- Chamado uma vez que o DOM foi carregado. Isso é igual a $ (document) .ready (function () {});

Yesu Raj
fonte
1
Alguém é capaz de obter isso? Eu já vi essa declaração em muitos fóruns, mas nunca com um link para onde ela está definida na especificação.
Crempp #
1
@crempp Há o elemento body e atributos globais , então eu diria que isso não é verdade. Mas você pode testar isso sozinho, consulte jsbin.com/OmiViPAJ/1/edit . Lá, você pode ver que o evento onload da imagem é acionado antes do evento onload do corpo.
Olaf Dietsche
2
Esta resposta contradiz outros; você pode fornecer uma fonte?
Jimmy Breck-McKye
2
api.jquery.com/ready Os documentos do jQuery dizem: "O método .ready () geralmente é incompatível com o atributo <body onload =" ">>". Eu acho que no jQuery é mais próximo do body.onload $ (window) .load (..) mas acho que eles ainda são diferentes.
ccsakuweb
2
Esta resposta está completamente errada e não deve ter nenhum voto positivo. De fato, esse tipo de resposta é geralmente citado como um dos maiores equívocos sobre eventos readyvs. é acionado após o carregamento do documento inteiro, incluindo todos os scripts, imagens e folhas de estilo. dispara depois que a árvore do DOM foi criada, mas antes das imagens etc. É a que tem equivalência , não . onloadloadDOMContentLoadedDOMContentLoadeddocument.readyload
RISM
2

Não diferença ...

Então, principalmente, você pode usar os dois (um de cada vez! -)

Mas, para facilitar a leitura e a limpeza do código html, eu sempre prefiro o window.onload! O]

roenving
fonte
1

Se você está tentando escrever um código JS discreto (e deveria), não deve usar <body onload="">.

Entendo que navegadores diferentes lidam com esses dois de maneira um pouco diferente, mas eles operam da mesma forma. Na maioria dos navegadores, se você definir os dois, um será ignorado.

Dr. Bob
fonte
1

Pense em onload como qualquer outro atributo. Em uma caixa de entrada, por exemplo, você pode colocar:

<input id="test1" value="something"/>

Ou você pode ligar para:

document.getElementById('test1').value = "somethingelse";

O atributo onload funciona da mesma maneira, exceto pelo fato de ter uma função como seu valor, em vez de uma string como o atributo value. Isso também explica por que você pode "usar apenas um deles" - chamar window.onload reatribui o valor do atributo onload para a tag body.

Além disso, como outros aqui estão dizendo, geralmente é mais fácil manter o estilo e o javascript separados do conteúdo da página, e é por isso que a maioria das pessoas aconselha o uso do window.onload ou da função pronta do jQuery.

Soldarnal
fonte
1

<body onload = ""> deve substituir window.onload.

Com <body onload = "">, document.body.onload pode ser nulo, indefinido ou uma função dependendo do navegador (embora getAttribute ("onload") deva ser um pouco consistente para obter o corpo da função anônima como uma string) . Com window.onload, quando você atribui uma função a ela, window.onload será uma função consistente nos navegadores. Se isso lhe interessa, use window.onload.

window.onload é melhor para separar o JS do seu conteúdo de qualquer maneira. Não há muitas razões para usar <body onload = ""> de qualquer maneira quando você pode usar window.onload.

No Opera, o destino do evento para window.onload e <body onload = ""> (e até window.addEventListener ("load", func, false)) será a janela em vez do documento, como no Safari e Firefox. Mas, 'this' será a janela entre os navegadores.

O que isso significa é que, quando for importante, você deve agrupar as coisas e tornar as coisas consistentes ou usar uma biblioteca que faça isso por você.

Shadow2531
fonte
0

Ambos trabalham da mesma maneira. No entanto, observe que, se os dois estiverem definidos, apenas um deles será chamado. Eu geralmente evito usar qualquer um deles diretamente. Em vez disso, você pode anexar um manipulador de eventos ao evento load. Dessa forma, você pode incorporar mais facilmente outros pacotes JS que também podem precisar anexar um retorno de chamada ao evento onload.

Qualquer estrutura JS terá métodos entre navegadores para manipuladores de eventos.

KernelM
fonte
0

É um padrão aceito separar conteúdo, layout e comportamento. Portanto, window.onload () será mais adequado para uso do que <body onload="">se ambos fizerem o mesmo trabalho.

Rajeshwaran SP
fonte
0

Desculpe pela reencarnação desse tópico novamente depois de mais 3 anos de sono, mas talvez eu finalmente tenha encontrado o benefício indiscutível de window.onload=fn1;mais <body onload="fn1()">. Trata-se dos módulos JS ou ES : quando o onloadmanipulador reside no arquivo JS "clássico" (ou seja, referido sem <script type="module" … >, de qualquer forma é possível; quando o onloadmanipulador reside no arquivo JS "módulo" (ou seja, referido <script type="module" … >, o <body onload="fn1()">erro ocorre com "fn1 () não está definido "error. O motivo talvez seja que os módulos ES não são carregados antes que o HTML seja analisado ... mas é apenas o meu palpite. De qualquer forma, window.onload=fn1;funciona perfeitamente com os módulos ...

Petr Pivonka
fonte