jQuery: Po co używać document.ready, jeśli zewnętrzny JS na dole strony?

88

Dołączam wszystkie moje JS jako pliki zewnętrzne, które są ładowane na samym dole strony. W tych plikach mam kilka zdefiniowanych w ten sposób metod, które wywołuję z gotowego zdarzenia:

var SomeNamepsace = {};

SomeNamepsace.firstMethod = function () {
    // do something
};

SomeNamepsace.secondMethod = function () {
    // do something else
};

$(document).ready(function () {
    SomeNamepsace.firstMethod();
    SomeNamepsace.secondMethod();
});

Jednak kiedy usuwam funkcję ready i wywołuję metody prosto do góry, wszystko działa tak samo, ale wykonuje się znacznie szybciej - prawie całą sekundę szybciej na całkiem podstawowym pliku! Skoro dokument powinien zostać załadowany w tym momencie (ponieważ wszystkie znaczniki znajdują się przed znacznikami skryptu), czy jest jakiś dobry powód, aby nadal używać zdarzenia ready?

niespokojny design
źródło
9
Interesujące pytanie. Niestety obecne odpowiedzi tak naprawdę nie odpowiadają na pytanie i nie mam też żadnych dobrych odpowiedzi. Może pomogłoby przeformułowanie pytania w ten sposób: „czy umieszczenie dokumentów JavaScript na końcu pliku gwarantuje, że DOM zostanie załadowany przed wykonaniem”
Boris Callens

Odpowiedzi:

116

Świetne pytanie.

Istnieje pewne zamieszanie wokół całej porady dotyczącej umieszczania skryptów na dole strony oraz problemu (ów), które próbuje on rozwiązać. W przypadku tego pytania nie będę mówić o tym, czy umieszczanie skryptów na dole strony wpływa na wydajność / czas ładowania, czy nie. Powiem tylko o tym, czy potrzebujesz, $(document).ready jeśli umieścisz skrypty na dole strony .

Zakładam, że odwołujesz się do DOM w tych funkcjach, które natychmiast wywołujesz w swoich skryptach (wszystko tak proste, jak documentlub document.getElementById). Zakładam również, że pytasz tylko o te pliki [odwołujące się do DOM]. IOW, skrypty biblioteczne lub skrypty, których wymaga Twój kod odwołujący się do DOM (np. JQuery), należy umieścić wcześniej na stronie.

Odpowiadając na pytanie : jeśli umieścisz skrypty odwołujące się do DOM na dole strony, nie, nie potrzebujesz $(document).ready.

Wyjaśnienie : bez pomocy "onload"powiązanych implementacji, jak praktyczna $(document).readyzasada: każdy kod, który wchodzi w interakcję z elementami DOM na stronie, powinien być umieszczony / zawarty dalej w dół strony niż elementy, do których się odwołuje. Najłatwiej jest umieścić ten kod przed zamknięciem </body>. Zobacz tutaj i tutaj . Działa również wokół przerażającego błędu IE „Operacja przerwana” .

Powiedziawszy to, w żadnym wypadku nie unieważnia to użycia $(document).ready. Odwoływanie się do obiektu przed jego załadowaniem jest [jednym z] najczęstszych błędów popełnianych podczas rozpoczynania pracy w DOM JavaScript (było to zbyt wiele razy, aby je zliczyć). Jest to rozwiązanie problemu przez jQuery i nie wymaga zastanawiania się, gdzie ten skrypt zostanie uwzględniony w stosunku do elementów DOM, do których się odwołuje. To ogromna wygrana dla programistów. To tylko jedna rzecz mniej, o której muszą myśleć.

Ponadto często trudne lub niepraktyczne jest przeniesienie wszystkich skryptów odwołujących się do DOM na dół strony (na przykład każdy skrypt, który document.writewywołuje wywołania, musi pozostać na miejscu). Innym razem używasz frameworka, który renderuje jakiś szablon lub tworzy fragmenty dynamicznego javascript, w którym odwołuje się do funkcji, które muszą być zawarte przed js.

Wreszcie, „najlepszą praktyką” było zagłuszanie całego kodu odwołującego się do DOM window.onload, jednak zostało przyćmione przez $(document).readyimplementacje z powodów dobrze udokumentowanych .

Wszystko to stanowi $(document).readyo wiele lepsze, praktyczne i ogólne rozwiązanie problemu zbyt wczesnego odwoływania się do elementów DOM.

Crescent Fresh
źródło
5
„Jeśli umieścisz skrypty odwołujące się do DOM na dole strony, nie, nie potrzebujesz $ (document) .ready.” Ignorując problem document.write, o którym mowa w dalszej części postu, ta odpowiedź zakłada naiwne założenie, że cały CSS jest pobierany i przetwarzany przed uruchomieniem javascript. To może nie być prawdą; przeglądarki mogą równolegle pobierać pliki zewnętrzne.
Powerlord
8
nie do końca poprawne, jeśli masz defergotowy dokument skryptów, zapewni ich wykonanie przed gotowym kodem. patrz: w3.org/TR/html5/the-end.html#the-end
Sam Saffron,