J'ai quelques <script>
éléments, et le code de certains d'entre eux dépend du code d'autres <script>
éléments. J'ai vu que l' defer
attribut peut être utile ici car il permet de retarder l'exécution des blocs de code.
Pour le tester, j'ai exécuté ceci sur Chrome: http://jsfiddle.net/xXZMN/ .
<script defer="defer">alert(2);</script>
<script>alert(1)</script>
<script defer="defer">alert(3);</script>
Cependant, il alerte 2 - 1 - 3
. Pourquoi ne l'alerte- 1 - 2 - 3
t- il pas ?
defer
n'est valable que lors de la spécificationsrc
. Cela pourrait être une raison pour laquelle votre exemple n'a pas fonctionné comme prévu dans la plupart des navigateurs.Réponses:
MISE À JOUR: 19/02/2016
Considérez cette réponse comme obsolète. Référez-vous à d'autres réponses sur ce post pour des informations pertinentes pour la nouvelle version du navigateur.
Fondamentalement, différer indique au navigateur d'attendre "jusqu'à ce qu'il soit prêt" avant d'exécuter le javascript dans ce bloc de script. Habituellement, c'est après que le DOM a fini de charger et de document.readyState == 4
L'attribut defer est spécifique à Internet Explorer. Dans Internet Explorer 8, sur Windows 7, le résultat que je vois dans votre page de test JS Fiddle est 1 - 2 - 3.
Les résultats peuvent varier d'un navigateur à l'autre.
http://msdn.microsoft.com/en-us/library/ms533719(v=vs.85).aspx
Contrairement à la croyance populaire, IE suit les normes plus souvent que les gens ne le disent, en réalité l'attribut "defer" est défini dans la spécification DOM niveau 1 http://www.w3.org/TR/REC-DOM-Level-1/level -one-html.html
La définition du W3C de différer: http://www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer :
"Lorsqu'il est défini, cet attribut booléen indique à l'agent utilisateur que le script ne va pas générer de contenu de document (par exemple, pas de" document.write "en javascript) et ainsi, l'agent utilisateur peut continuer l'analyse et le rendu."
la source
Quelques extraits de la spécification HTML5: http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async
la source
defer
mal . Si vous utilisezdefer
, vous ne pouvez pas vous fier aux fichiers de script exécutés dans l'ordre dans certains navigateurs.La vraie réponse est: parce que vous ne pouvez pas faire confiance à différer.
Dans le concept, différer et asynchroniser diffèrent comme suit:
async permet de télécharger le script en arrière-plan sans le bloquer. Ensuite, au moment où il termine le téléchargement, le rendu est bloqué et ce script s'exécute. Le rendu reprend une fois le script exécuté.
reporter fait la même chose, sauf qu'il prétend garantir que les scripts s'exécutent dans l'ordre où ils ont été spécifiés sur la page, et qu'ils seront exécutés une fois l'analyse du document terminée. Ainsi, certains scripts peuvent terminer le téléchargement puis s'asseoir et attendre les scripts téléchargés plus tard mais apparus devant eux.
Malheureusement, en raison de ce qui est vraiment un combat de chats standard, la définition de defer varie selon les spécifications, et même dans les spécifications les plus récentes, n'offre pas de garantie utile. Comme les réponses ici et ce problème le démontrent, les navigateurs implémentent différer différemment:
defer
dysfonctionnement des scripts.DOMContentLoaded
événement jusqu'à ce que lesdefer
scripts soient chargés, et d'autres non.defer
à des<script>
éléments avec du code en ligne et sanssrc
attribut, et certains l'ignorent.Heureusement, la spécification spécifie au moins que les substitutions asynchrones reportent. Ainsi, vous pouvez traiter tous les scripts comme asynchrones et obtenir une large gamme de support de navigateur comme ceci:
98% des navigateurs utilisés dans le monde et 99% aux États-Unis éviteront le blocage avec cette approche.
(Si vous devez attendre la fin de l'analyse du document, écoutez l'événement d'
DOMContentLoaded
événement ou utilisez la.ready()
fonction pratique de jQuery . Vous voudrez quand même le faire pour vous rabattre gracieusement sur les navigateurs qui ne l'implémentent pasdefer
du tout.)la source
defer
attribut depuis la version 15 , qui a été publiée le 2 juin 2013 .defer
ne peut être utilisé que dans la<script>
balise pour l' inclusion de script externe . Par conséquent, il est conseillé de l'utiliser dans les<script>
balises-de la section<head>
.la source
Comme l'attribut defer ne fonctionne qu'avec la balise scripts avec src. Trouvé un moyen d'imiter le report des scripts en ligne. Utilisez l'événement DOMContentLoaded.
En effet, l'événement DOMContentLoaded se déclenche après le chargement complet des scripts attribués différés.
la source
L'attribut defer est uniquement pour les scripts externes (ne doit être utilisé que si l'attribut src est présent).
la source
Il convient également de noter qu'il peut y avoir des problèmes dans IE <= 9 lors de l'utilisation
script defer
dans certaines situations. Plus d'informations à ce sujet: https://github.com/h5bp/lazyweb-requests/issues/42la source
Jetez un œil à cet excellent article Plongez dans les eaux troubles du chargement de scripts par le développeur Google Jake Archibald écrit en 2013.
Citant la section pertinente de cet article:
(J'ajouterai que les premières versions de Firefox déclenchent DOMContentLoaded avant la
defer
fin des scripts, selon ce commentaire .)Les navigateurs modernes semblent prendre en charge
async
correctement, mais vous devez être d'accord avec les scripts en panne et éventuellement avant DOMContentLoaded.la source
Cet attribut booléen est défini pour indiquer à un navigateur que le script est destiné à être exécuté après l'analyse du document. Étant donné que cette fonctionnalité n'a pas encore été implémentée par tous les autres principaux navigateurs, les auteurs ne doivent pas supposer que l'exécution du script sera réellement différée. N'appelez jamais document.write () à partir d'un script différé (depuis Gecko 1.9.2, cela détruirait le document). L'attribut defer ne doit pas être utilisé sur des scripts qui n'ont pas l'attribut src. Depuis Gecko 1.9.2, l'attribut defer est ignoré sur les scripts qui n'ont pas l'attribut src. Cependant, dans Gecko 1.9.1, même les scripts en ligne sont différés si l'attribut defer est défini.
defer fonctionne avec Chrome, Firefox, c'est-à-dire> 7 et Safari
réf: https://developer.mozilla.org/en-US/docs/HTML/Element/script
la source
L'attribut defer est un attribut booléen.
Lorsqu'il est présent, il spécifie que le script est exécuté lorsque la page a terminé l'analyse.
Remarque: L'attribut defer est uniquement pour les scripts externes (ne doit être utilisé que si l'attribut src est présent).
Remarque: Il existe plusieurs façons d'exécuter un script externe:
Si async est présent: le script est exécuté de manière asynchrone avec le reste de la page (le script sera exécuté pendant que la page continue l'analyse) Si async n'est pas présent et différé est présent: Le script est exécuté lorsque la page a terminé l'analyse Si ni async ni report n'est présent: le script est récupéré et exécuté immédiatement, avant que le navigateur ne continue d'analyser la page
la source