У меня есть несколько <script>
элементов, и код в некоторых из них зависит от кода в других <script>
элементах. Я видел, что defer
атрибут может пригодиться здесь, поскольку он позволяет откладывать блоки кода в процессе выполнения.
Чтобы проверить это, я выполнил это на Chrome: http://jsfiddle.net/xXZMN/ .
<script defer="defer">alert(2);</script>
<script>alert(1)</script>
<script defer="defer">alert(3);</script>
Тем не менее, это предупреждает 2 - 1 - 3
. Почему это не насторожило 1 - 2 - 3
?
javascript
html
deferred-execution
pimvdb
источник
источник
defer
действует только при указанииsrc
. Это может быть причиной того, что ваш пример не работает должным образом в большинстве браузеров.Ответы:
ОБНОВЛЕНО: 19.02.2016
Считайте этот ответ устаревшим. Обратитесь к другим ответам на этот пост для получения информации, относящейся к более новой версии браузера.
По сути, defer указывает браузеру подождать «пока он не будет готов», прежде чем выполнять javascript в этом блоке сценария. Обычно это происходит после завершения загрузки DOM и document.readyState == 4
Атрибут defer относится только к Internet Explorer. В Internet Explorer 8 в Windows 7 результат, который я вижу на вашей тестовой странице JS Fiddle, 1 - 2 - 3.
Результаты могут отличаться от браузера к браузеру.
http://msdn.microsoft.com/en-us/library/ms533719(v=vs.85).aspx
Вопреки распространенному мнению, IE следует стандартам чаще, чем люди допускают, в действительности атрибут defer определен в спецификации DOM Level 1 http://www.w3.org/TR/REC-DOM-Level-1/level -он-html.html
Определение отсрочки в W3C: http://www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer :
«Когда этот атрибут установлен, этот логический атрибут подсказывает агенту пользователя, что сценарий не будет генерировать никакого содержимого документа (например, нет« document.write »в javascript), и, таким образом, агент пользователя может продолжить анализ и рендеринг».
источник
Несколько фрагментов из спецификации HTML5: http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async
источник
defer
плохо работают . Если вы используетеdefer
, вы не можете полагаться на файлы сценариев, выполняемые по порядку в некоторых браузерах.Реальный ответ: потому что вы не можете доверять отсрочке.
Концептуально, defer и async отличаются следующим образом:
асинхронной позволяет загружать скрипт в фоновом режиме без блокировки. Затем, в момент завершения загрузки, рендеринг блокируется, и этот скрипт выполняется. Визуализация возобновляется после выполнения сценария.
defer делает то же самое, за исключением утверждений, гарантирующих, что сценарии выполняются в том порядке, в котором они были указаны на странице, и что они будут выполняться после завершения анализа документа. Таким образом, некоторые сценарии могут закончить загрузку, а затем сидеть и ждать сценариев, которые загружались позже, но появлялись перед ними.
К сожалению, из-за того, что на самом деле является стандартным сражением, определение defer варьируется от спецификации к спецификации, и даже в самых последних спецификациях не дает полезной гарантии. Как показывают ответы здесь и эта проблема , браузеры по-разному реализуют отсрочку:
defer
скрипты работают не по порядку.DOMContentLoaded
событие до тех пор, покаdefer
скрипты не загрузятся, а некоторые - нет.defer
на<script>
элементах с инлайн кодом и безsrc
атрибута, и некоторые его игнорировать.К счастью, в спецификации, по крайней мере, указано, что асинхронные переопределения отложены. Таким образом, вы можете рассматривать все сценарии как асинхронные и получать широкую поддержку браузеров следующим образом:
При таком подходе 98% браузеров, используемых по всему миру, и 99% в США избежат блокировки.
(Если вам нужно подождать, пока документ не завершит синтаксический анализ, прослушайте событие
DOMContentLoaded
события или воспользуйтесь удобной.ready()
функцией jQuery. В любом случае вы захотите сделать это, чтобы элегантно использовать браузеры, которые вообще не реализуютсяdefer
.)источник
defer
атрибут с версии 15 , которая была выпущена 2 июня 2013 года .defer
может использоваться только в<script>
теге для включения внешнего скрипта . Следовательно, рекомендуется использовать в<script>
-tags в<head>
-section.источник
Атрибут defer работает только с тегами scripts с src. Нашел способ подражать defer для встроенных скриптов. Используйте событие DOMContentLoaded.
Это связано с тем, что событие DOMContentLoaded возникает после полной загрузки отложенных сценариев.
источник
Атрибут defer предназначен только для внешних сценариев (должен использоваться только при наличии атрибута src).
источник
Следует также отметить, что могут быть проблемы в IE <= 9 при использовании
script defer
в определенных ситуациях. Подробнее об этом: https://github.com/h5bp/lazyweb-requests/issues/42источник
Взгляните на эту прекрасную статью « Глубокое погружение в мутные воды загрузки скриптов », разработанную разработчиком Google Джейком Арчибальдом, написанную в 2013 году.
Цитирую соответствующий раздел из этой статьи:
(Я добавлю, что ранние версии Firefox вызывают DOMContentLoaded до завершения работы
defer
сценариев, согласно этому комментарию .)Современные браузеры, кажется, поддерживают
async
должным образом, но вы должны быть в порядке со сценариями, работающими не по порядку и, возможно, до DOMContentLoaded.источник
Этот логический атрибут устанавливается для указания браузеру, что сценарий должен выполняться после анализа документа. Поскольку эта функция еще не была реализована во всех других основных браузерах, авторы не должны предполагать, что выполнение сценария будет фактически отложено. Никогда не вызывайте document.write () из отложенного скрипта (начиная с Gecko 1.9.2, это уничтожит документ). Атрибут defer не должен использоваться в сценариях, которые не имеют атрибута src. Начиная с Gecko 1.9.2, атрибут defer игнорируется в сценариях, которые не имеют атрибута src. Однако в Gecko 1.9.1 даже встроенные скрипты откладываются, если установлен атрибут defer.
defer работает с Chrome, Firefox, т.е.> 7 и Safari
ссылка: https://developer.mozilla.org/en-US/docs/HTML/Element/script
источник
Атрибут defer является логическим атрибутом.
Когда он присутствует, он указывает, что скрипт выполняется, когда страница закончила анализ.
Примечание. Атрибут defer предназначен только для внешних сценариев (должен использоваться только при наличии атрибута src).
Примечание. Существует несколько способов выполнения внешнего скрипта:
Если присутствует асинхронность: сценарий выполняется асинхронно с остальной частью страницы (сценарий будет выполняться, пока страница продолжит синтаксический анализ) Если асинхронность отсутствует и присутствует отсрочка: сценарий выполняется после завершения анализа страницы. нет ни асинхронного, ни отложенного: скрипт извлекается и выполняется немедленно, прежде чем браузер продолжит анализ страницы
источник