window.onload vs <body onload = „” />

227

Jaka jest dokładnie różnica między window.onloadzdarzeniem a onloadzdarzeniem bodytagu? kiedy mam użyć które i jak należy to zrobić poprawnie?

Manu
źródło
2
powinieneś użyć „, aby otoczyć wartość atrybutu
Sven Larson

Odpowiedzi:

218

window.onload = myOnloadFunci <body onload="myOnloadFunc();">są różne sposoby korzystania z tego samego wydarzenia . Korzystanie window.onloadjest jednak mniej nachalne - usuwa JavaScript z HTMLa.

Wszystkie popularne biblioteki JavaScript, Prototyp, ExtJS, Dojo, JQuery, YUI itp. Zapewniają ładne opakowanie wokół zdarzeń pojawiających się podczas ładowania dokumentu. Możesz nasłuchiwać zdarzenia okna onLoad i reagować na to, ale onLoad nie jest uruchamiany, dopóki nie zostaną pobrane wszystkie zasoby, więc program obsługi zdarzeń nie zostanie uruchomiony, dopóki nie zostanie pobrany ostatni wielki obraz. W niektórych przypadkach jest to dokładnie to, czego chcesz, w innych może się okazać, że nasłuchiwanie, gdy DOM jest gotowy, jest bardziej odpowiednie - to zdarzenie jest podobne do onLoad, ale jest uruchamiane bez oczekiwania na pobranie obrazów itp.

Richard Turner
źródło
57
Należy jednak zauważyć, że istnieje różnica. Zdarzenie inline onload będzie wywoływać myOnloadFunc()w kontekście globalnym ( thisbędzie się odnosić window). Ustawienie go za pomocą javascript spowoduje, że będzie on wykonywany w kontekście elementu ( thisodnosi się do elementu, w którym zdarzenie zostało wywołane). W tym konkretnym przypadku nie zrobi to różnicy, ale zrobi to z innymi elementami.
mowwwalker
1
@Walkerneo: Tak, zdecydowanie warte odnotowania. Oczywiście za pomocą biblioteki JS można w thisrazie potrzeby zastąpić obiekt, do którego się odnosi.
Richard Turner
@RichardTurner Nie musisz używać biblioteki, aby zmienić powiązanie kontekstu. Tak robi proste wywołanie
.bind
@Kloar możesz teraz, tak, ale potrzebujesz MSIE9 +. Na starszej wersji MSIE, która była o wiele bardziej powszechna, kiedy odpowiadałem, potrzebna byłaby polifill.
Richard Turner
33

Nie ma różnicy, ale nie powinieneś również używać.

W wielu przeglądarkach window.onloadzdarzenie nie jest uruchamiane, dopóki wszystkie obrazy nie zostaną załadowane, co nie jest tym, czego chcesz. Przeglądarki oparte na standardach mają wywoływane zdarzenie, DOMContentLoadedktóre uruchamia się wcześniej, ale nie jest obsługiwane przez IE (w momencie pisania tej odpowiedzi). Polecam użycie biblioteki javascript, która obsługuje funkcję DOMContentLoaded w różnych przeglądarkach, lub znalezienie dobrze napisanej funkcji, której można użyć. jQuery's $(document).ready()jest dobrym przykładem.

jcampbell1
źródło
53
Pytanie z przyszłości ... Co jeśli nie będzie jquery?
Sid
54
Pytanie z teraźniejszości. Co zrobić, jeśli jQuery ma nadmiar umiejętności w stosunku do projektu? (Nie puka jQuery, użyj go sam. Tylko czasami chcę tylko jednej funkcji z biblioteki ..)
Bradmage
14
Kiedy mówisz „nieobsługiwany przez IE”, czy jest to uniwersalna prawda, czy tylko prawdziwa dla określonych wersji IE? Ponieważ wiele zmieniło się w świecie przeglądarki, odkąd napisałeś tę odpowiedź, może czas ją zaktualizować?
Bryan Oakley
8
DOMContentLoaded jest teraz obsługiwany przez IE9 i nowsze wersje: developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Adam
6
Raportowanie z przyszłości, DOMContentLoaded jest teraz obsługiwany przez wszystkie główne przeglądarki: caniuse.com/#feat=domcontentloaded
Jose Gómez
21

window.onloadmoże pracować bez ciała. Utwórz stronę zawierającą tylko tagi skryptu i otwórz ją w przeglądarce. Strona nie zawiera treści, ale nadal działa ...

<script>
  function testSp()
  {
    alert("hit");
  }
  window.onload=testSp;
</script>
John Joseph
źródło
6
HTML bez tagu body jest nieprawidłowy, jeśli faktycznie dodajesz treść (która powinna znajdować się w tagu body). Również w tagu skryptu brakuje typu. Nigdy nie polegaj na przeglądarkach, które naprawiają niestandardowy kod! (Ponieważ przeglądarki mogą robić to inaczej lub wcale nie w przeszłości lub w przyszłości.)
Kissaki
4
@ Kissaki: Standardowy HTML w ogóle nie potrzebuje tagu treści!
Robert Siemer
5
xhtml1 określa <!ELEMENT html (head, body)>[1] - i html401 Określa <!ELEMENT HTML O O (%html.content;)z <!ENTITY % html.content "HEAD, BODY">oraz [2]. html51 stwierdza również A head element followed by a body element.dla treści 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-elementowa - Sądzę więc, że wszystkie z tych standardów HTML common / w obsłudze zrobić wymagają tag ciała. :)
Kissaki
1
@Kissaki to XHTML, a nie HTML. HTML pozwala na pomijanie zarówno znaczników początkowych, jak i końcowych, a także pomijanie znaczników html i head, zgodnie z DTD SGML. w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoded
1
@Kissaki: html5 nie potrzebuje już typu skryptu (jeśli to javascript), jesteś odpowiedni dla wcześniejszych wersji.
Mark
10

Ogólnie wolę nie używać <body onload=""zdarzenia. Myślę, że czystsze jest zachowanie zachowania w jak największym stopniu oddzielone od treści.

To powiedziawszy, są sytuacje (zwykle dla mnie dość rzadkie), w których użycie obciążenia ciała może nieco przyspieszyć.

Lubię używać Prototype, więc na ogół umieszczam coś takiego w <head>> mojej stronie:

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

lub

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

Powyższe to sztuczki, których nauczyłem się tutaj . Bardzo podoba mi się koncepcja dołączania obsługi zdarzeń poza HTML.

(Edytuj, aby poprawić błąd pisowni w kodzie).

Mark Biek
źródło
W jakich sytuacjach byłoby to szybsze i dlaczego?
Kissaki,
Ta odpowiedź wydaje się bardzo subiektywna w przypadku wszystkich „ja” („wolę”, „myślę”). To, że w dalszym ciągu brakuje jakichkolwiek obiektywnych i weryfikowalnych faktów, w dużym stopniu potwierdza to wrażenie.
Kissaki,
1
Wziąłbym tę odpowiedź z odrobiną soli, biorąc pod uwagę, że została opublikowana ponad 6 lat temu. Zapraszamy do aktualizacji lub opublikowania własnej poprawionej odpowiedzi.
Mark Biek
7

„tak wiele subiektywnych odpowiedzi na obiektywne pytanie. „Nienarzucający się” JavaScript to przesąd jak stara zasada, by nigdy nie używać gotos. Napisz kod w sposób, który pomoże ci niezawodnie osiągnąć swój cel, a nie zgodnie z czyimiś modnymi przekonaniami religijnymi.

Każdy, kto znajdzie:

 <body onload="body_onload();">

zbytnie rozpraszanie jest zbyt pretensjonalne i nie ma prostych priorytetów.

Zwykle umieszczam swój kod JavaScript w osobnym pliku .js, ale nie mam nic kłopotliwego w przechwytywaniu procedur obsługi zdarzeń w HTML, który jest przy okazji prawidłowym HTML.


źródło
39
Jest dobry powód, aby pisać dyskretny javascript. Załóżmy, że masz aplikację internetową zawierającą 100 stron i użyłeś metody <body onload = "body_onload ();"> zamiast umieszczać ją w pliku javascript zawartym na każdej stronie. Wyobraź sobie, że z jakiegoś powodu musisz zmienić nazwę tej funkcji. Umieszczenie zdarzenia w dołączonym pliku javascript 1) sprawia, że ​​zmiany są znacznie prostsze, a 2) oszczędza zasoby serwera, ponieważ pliki javascript można buforować przez rok (na odpowiednio skonfigurowanym serwerze) zamiast pobierać ten sam kod w kółko.
Andrew Ensley,
21
Ponieważ nie zadajesz sobie trudu, aby dowiedzieć się, dlaczego coś jest zalecane, nazwij zalecenia „modnymi przekonaniami religijnymi”?
hallvors
6
Pytanie brzmi: „Jaka jest różnica między tymi dwiema metodami?”, Wraz z prośbą o rekomendację, która jest lepsza. Jak twoja odpowiedź odpowiada na to pytanie?
Richard Turner
1
Każda sytuacja, w której tworzysz modułowe rozwiązanie w jednym miejscu, które można zastosować do dużej liczby plików, jest o wiele lepsze niż dodawanie kodu do każdego z samych plików. Jest lepszy w przypadku oryginalnego czasu kompilacji, celów organizacyjnych kodu, czytelności i przyszłej edycji. To nie jest modne, w rzeczywistości jest to starsza koncepcja obecna w językach takich jak Java i C ++, które programiści internetowi uznają teraz za znacznie lepszy sposób na kodowanie.
Jimbo Jonny,
1
Jedną dobrą obroną przed atakami XSS we współczesnych przeglądarkach jest wyłączenie wszystkich wbudowanych javascript z Polityką bezpieczeństwa treści. To całkiem dobry powód, aby nie używać atrybutu onload w kodzie HTML.
Greg Ball
4

window.onload- Wywoływany po całkowitym załadowaniu wszystkich plików DOM, JS, obrazów, ramek iframe, rozszerzeń i innych. Jest to równe $ (okno) .load (function () {});

body onload=""- Wywoływany po załadowaniu DOM. Jest to równe $ (dokument) .ready (function () {});

Yesu Raj
źródło
1
Czy ktoś może to zdobyć? Widziałem to oświadczenie na wielu forach, ale nigdy z linkiem do miejsca, w którym jest zdefiniowane w specyfikacji.
crempp
1
@crempp Istnieje element body i atrybuty globalne , więc powiedziałbym, że to nieprawda. Ale możesz to przetestować sam, patrz jsbin.com/OmiViPAJ/1/edit . Tam można zobaczyć, że zdarzenie obciążenia obrazu jest uruchamiane przed zdarzeniem obciążenia ciała.
Olaf Dietsche
2
Ta odpowiedź jest sprzeczna z innymi; czy możesz podać źródło?
Jimmy Breck-McKye
2
api.jquery.com/ready Dokumentacja jQuery mówi: „Metoda .ready () jest zasadniczo niezgodna z atrybutem <body onload =" ">." Myślę, że w jQuery jest bardziej zbliżony do body.onload $ (window) .load (..), ale myślę, że nadal są różne.
ccsakuweb
2
Ta odpowiedź jest całkowicie błędna i nie powinna mieć żadnych głosów. W rzeczywistości ten rodzaj odpowiedzi jest ogólnie cytowany jako jeden z największych nieporozumień na temat wydarzeń readyvs. uruchamia się po załadowaniu całego dokumentu, w tym wszystkich skryptów, obrazów i arkuszy stylów. odpala po zbudowaniu drzewa DOM, ale przed obrazami itp. Jego odpowiednik to nie . onloadloadDOMContentLoadedDOMContentLoadeddocument.readyload
rism
2

Nie ma różnicy ...

Więc zasadniczo możesz korzystać z obu (pojedynczo! -)

Ale ze względu na czytelność i czystość kodu HTML zawsze wolę window.onload! O]

rykanie
źródło
1

Jeśli próbujesz napisać dyskretny kod JS (i powinieneś być), nie powinieneś go używać <body onload="">.

Rozumiem, że różne przeglądarki traktują te dwie nieco inaczej, ale działają podobnie. W większości przeglądarek, jeśli zdefiniujesz oba, jedna zostanie zignorowana.

Dr Bob
źródło
1

Pomyśl o obciążeniu jak o każdym innym atrybucie. Na przykład w polu wprowadzania danych możesz umieścić:

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

Lub możesz zadzwonić:

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

Atrybut onload działa w ten sam sposób, z tą różnicą, że przyjmuje funkcję jako swoją wartość zamiast łańcucha, podobnie jak atrybut value. To wyjaśnia również, dlaczego można „użyć tylko jednego z nich” - wywołanie window.onload ponownie przypisuje wartość atrybutu onload dla tagu body.

Ponadto, jak mówią inni tutaj, zwykle czystsze jest utrzymywanie stylu i javascript oddzielonych od zawartości strony, dlatego większość osób zaleca używanie window.onload lub podobnej funkcji jQuery.

Soldarnal
źródło
1

<body onload = ""> powinien zastąpić window.onload.

W przypadku <body onload = ""> document.body.onload może mieć wartość null, niezdefiniowaną lub funkcję zależną od przeglądarki (chociaż getAttribute („onload”) powinien być dość spójny, aby uzyskać treść funkcji anonimowej jako ciąg znaków) . Dzięki window.onload, po przypisaniu do niego funkcji, window.onload będzie funkcją konsekwentnie we wszystkich przeglądarkach. Jeśli to dla Ciebie ważne, użyj window.onload.

Window.onload i tak lepiej oddziela JS od treści. Zresztą nie ma żadnego powodu, aby używać <body onload = "">, gdy można użyć window.onload.

W Operze celem zdarzenia dla window.onload i <body onload = ""> (a nawet window.addEventListener („load”, func, false)) będzie okno zamiast dokumentu, jak w Safari i Firefox. Ale „to” będzie oknem w różnych przeglądarkach.

Oznacza to, że gdy ma to znaczenie, powinieneś owinąć to miejsce i zapewnić spójność rzeczy lub skorzystać z biblioteki, która zrobi to za Ciebie.

Shadow2531
źródło
0

Oba działają tak samo. Należy jednak pamiętać, że jeśli oba są zdefiniowane, tylko jeden z nich zostanie wywołany. Generalnie unikam używania któregokolwiek z nich bezpośrednio. Zamiast tego możesz dołączyć moduł obsługi zdarzeń do zdarzenia load. W ten sposób można łatwiej włączyć inne pakiety JS, które mogą wymagać dołączenia wywołania zwrotnego do zdarzenia onload.

Każdy framework JS będzie miał metody obsługi różnych przeglądarek dla procedur obsługi zdarzeń.

Jądro
źródło
0

Jest przyjętym standardem oddzielenia treści, układu i zachowania. Tak więc window.onload () będzie bardziej odpowiedni do użycia niż <body onload="">oba wykonują tę samą pracę.

Rajeshwaran SP
źródło
0

Przepraszam za reinkarnację tego wątku ponownie po kolejnych 3 latach snu, ale być może w końcu znalazłem niepodważalną korzyść z window.onload=fn1;ponad <body onload="fn1()">. Dotyczy modułów JS lub modułów ES : gdy Twój onloadprogram obsługi znajduje się w „klasycznym” pliku JS (tzn. Odwoływanie się bez niego <script type="module" … >, jest to możliwe, gdy twój onloadprogram obsługi znajduje się w pliku JS „modułu” (tzn. W odniesieniu do niego <script type="module" … >, <body onload="fn1()">nie powiedzie się z „fn1 () nie jest zdefiniowany "błąd. Być może przyczyną jest to, że moduły ES nie są ładowane przed parsowaniem HTML… ale to tylko moje przypuszczenie. W każdym razie window.onload=fn1;działa idealnie z modułami ...

Petr Pivonka
źródło