Mam kilka <script>
elementów, a kod w niektórych z nich zależy od kodu w innych <script>
elementach. Widziałem, że ten defer
atrybut może się tu przydać, ponieważ umożliwia odłożenie bloków kodu w trakcie wykonywania.
Aby to przetestować, wykonałem to w Chrome: http://jsfiddle.net/xXZMN/ .
<script defer="defer">alert(2);</script>
<script>alert(1)</script>
<script defer="defer">alert(3);</script>
Ostrzega jednak 2 - 1 - 3
. Dlaczego nie alarmuje 1 - 2 - 3
?
javascript
html
deferred-execution
pimvdb
źródło
źródło
defer
obowiązuje tylko przy określaniusrc
. Może to być powód, dla którego twój przykład nie działał zgodnie z oczekiwaniami w większości przeglądarek.Odpowiedzi:
ZAKTUALIZOWANO: 19.02.2016
Uważaj tę odpowiedź za nieaktualną. Informacje na temat nowszej wersji przeglądarki znajdują się w innych odpowiedziach w tym poście.
Zasadniczo odroczenie mówi przeglądarce, aby poczekała „aż będzie gotowy” przed wykonaniem javascript w tym bloku skryptu. Zwykle dzieje się to po zakończeniu ładowania DOM i document.readyState == 4
Odroczony atrybut jest specyficzny dla przeglądarki internetowej. W przeglądarce Internet Explorer 8 w systemie Windows 7 wynik, który widzę na stronie testowej JS Fiddle, to 1–2–3.
Wyniki mogą się różnić w zależności od przeglądarki.
http://msdn.microsoft.com/en-us/library/ms533719(v=vs.85).aspx
Wbrew powszechnemu przekonaniu IE częściej stosuje standardy niż ludzie, w rzeczywistości atrybut „odroczenia” jest zdefiniowany w specyfikacji DOM Level 1 http://www.w3.org/TR/REC-DOM-Level-1/level -one-html.html
Definicja odroczenia W3C: http://www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer :
„Po ustawieniu ten atrybut logiczny daje wskazówkę dla agenta użytkownika, że skrypt nie będzie generował żadnej zawartości dokumentu (np. Brak„ document.write ”w javascript), a zatem agent użytkownika może kontynuować parsowanie i renderowanie.”
źródło
Kilka fragmentów ze specyfikacji HTML5: http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async
źródło
defer
źle się implementują . Jeśli używaszdefer
, nie możesz polegać na plikach skryptów wykonywanych po kolei w niektórych przeglądarkach.Prawdziwa odpowiedź brzmi: ponieważ nie możesz ufać odroczeniu.
W koncepcji odroczenia i asynchronizacji różnią się w następujący sposób:
async pozwala na pobranie skryptu w tle bez blokowania. Następnie, w momencie zakończenia pobierania renderowanie jest blokowane i skrypt jest wykonywany. Renderowanie zostanie wznowione po wykonaniu skryptu.
odroczenie robi to samo, z wyjątkiem roszczeń gwarantujących, że skrypty będą wykonywane w kolejności, w jakiej zostały określone na stronie, i że zostaną wykonane po zakończeniu analizy dokumentu. Dlatego niektóre skrypty mogą zakończyć pobieranie, a następnie usiąść i czekać na skrypty, które zostały pobrane później, ale pojawiły się przed nimi.
Niestety, ze względu na to, co tak naprawdę jest standardową walką kotów, definicja odroczenia różni się w zależności od specyfikacji, a nawet w najnowszych specyfikacjach nie daje użytecznej gwarancji. Jak pokazują odpowiedzi tutaj i ten problem , przeglądarki implementują odraczanie w inny sposób:
defer
skrypty nie działają.DOMContentLoaded
zdarzenie do momentudefer
załadowania skryptów, a niektóre nie.defer
się do<script>
elementów z wbudowanym kodem i bezsrc
atrybutu, a niektóre go ignorują.Na szczęście specyfikacja przynajmniej określa, że asynchronizacja zastępuje odroczenie. Możesz więc traktować wszystkie skrypty jako asynchroniczne i uzyskać szeroki wachlarz obsługi przeglądarki w następujący sposób:
98% przeglądarek używanych na całym świecie i 99% w USA uniknie blokowania przy takim podejściu.
(Jeśli musisz poczekać, aż dokument się zakończy parsowanie, wysłuchaj zdarzenia
DOMContentLoaded
zdarzenia lub skorzystaj z przydatnej.ready()
funkcji jQuery . Chciałbyś to zrobić i tak, abydefer
w pełni zrezygnować z przeglądarki, która w ogóle się nie implementuje ).źródło
defer
atrybut od wersji 15 , która została wydana 2 czerwca 2013 r .defer
może być użyty tylko w<script>
tagu do włączenia zewnętrznego skryptu . Dlatego zaleca się stosowanie w<script>
tagach w sekcji<head>
.źródło
Jako atrybut odroczenia działa tylko ze znacznikiem scripts z src. Znaleziono sposób naśladowania odroczenia dla skryptów wbudowanych. Użyj zdarzenia DOMContentLoaded.
Jest tak, ponieważ zdarzenie DOMContentLoaded jest uruchamiane po całkowitym załadowaniu odroczonych skryptów przypisanych.
źródło
Atrybut odroczenia dotyczy tylko zewnętrznych skryptów (należy go używać tylko wtedy, gdy występuje atrybut src).
źródło
Należy również zauważyć, że mogą występować problemy w IE <= 9 podczas korzystania
script defer
w niektórych sytuacjach. Więcej na ten temat: https://github.com/h5bp/lazyweb-requests/issues/42źródło
Zapoznaj się z tym doskonałym artykułem. Zanurz się w mętnych wodach ładowania skryptów przez programistę Google, Jake'a Archibalda z 2013 roku.
Cytując odpowiednią sekcję z tego artykułu:
(Dodam, że wczesne wersje Firefox wyzwalają DOMContentLoaded, zanim
defer
skrypty zakończą działanie, zgodnie z tym komentarzem ).Wygląda na to, że współczesne przeglądarki działają
async
poprawnie, ale musisz działać poprawnie, gdy skrypty działają nieprawidłowo i być może przed DOMContentLoaded.źródło
Ten atrybut boolowski jest ustawiony tak, aby wskazywał przeglądarce, że skrypt ma zostać wykonany po przeanalizowaniu dokumentu. Ponieważ ta funkcja nie została jeszcze zaimplementowana we wszystkich innych głównych przeglądarkach, autorzy nie powinni zakładać, że wykonanie skryptu zostanie odroczone. Nigdy nie wywoływaj document.write () ze skryptu odroczonego (od Gecko 1.9.2 spowoduje to zniszczenie dokumentu). Atrybutu odroczenia nie należy używać w skryptach, które nie mają atrybutu src. Od wersji Gecko 1.9.2 atrybut odroczenia jest ignorowany w skryptach, które nie mają atrybutu src. Jednak w Gecko 1.9.1 nawet wbudowane skrypty są odraczane, jeśli ustawiony jest atrybut odroczenia.
defer działa z Chrome, Firefox, tj.> 7 i Safari
ref: https://developer.mozilla.org/en-US/docs/HTML/Element/script
źródło
Odroczony atrybut jest atrybutem boolowskim.
Gdy jest obecny, określa, że skrypt jest wykonywany, gdy strona zakończy parsowanie.
Uwaga: Atrybut odroczenia dotyczy tylko skryptów zewnętrznych (należy go używać tylko wtedy, gdy występuje atrybut src).
Uwaga: Istnieje kilka sposobów wykonania zewnętrznego skryptu:
Jeśli async jest obecny: skrypt jest wykonywany asynchronicznie z resztą strony (skrypt zostanie wykonany, gdy strona będzie kontynuowała parsowanie) Jeśli asynchronia nie jest dostępna, a odroczenie jest obecne: skrypt jest wykonywany, gdy strona zakończy parsowanie Jeśli nie występuje ani asynchronizacja, ani odroczenie: skrypt jest pobierany i wykonywany natychmiast, zanim przeglądarka będzie dalej analizować stronę
źródło