document.write игнорируется перед DOMContentLoaded при ожидании загрузки скрипта с высокой задержкой - PullRequest
3 голосов
/ 21 марта 2012

Я безуспешно пытался сформулировать этот вопрос в Google et al.Даже не уверен, что название этого вопроса отражает нюанс проблемы.Я постараюсь объяснить, а затем показать эксперимент.Я надеюсь, что кто-то (ы) сможет указать на некоторые объяснения того, что происходит.

Учитывая:

  • до окончания ТЕЛА, у вас естьскрипт (A), который программно вставляет элемент скрипта (используя мой предпочтительный метод document.createElement) в документ, который ссылается на remote-script (B)
  • remote-script B, выполняет document.write любогоcontent (например, «hello, world»)
  • до конца BODY и сразу после сценария A у вас есть сценарий (C), который ссылается на удаленный сценарий, загрузка которого занимает некоторое время (например, 1 с)

Что произойдет, если A выполнит, вставит B в документ и начнет загружать ресурс.Пока B загружает, C будет выполняться и ждать из-за задержки.Пока C ожидает, B загружается и выполняется;мы еще не нажали DOMContentLoaded;document.readyState все еще "загружается".Document.write из B игнорируется;сожрал, как будто мы пост-DOMContentLoaded.C завершает загрузку и выполняет.

Эксперимент:

Я использую Cuzillion для созданиязадержка.Если вы посмотрите на изображение водопада, вы также увидите сообщение console.log, в котором показано, что все выполняется до того, как DOM выполнит «интерактивный» readyState (т. Е. DOMContentLoaded).

То, что я ожидаю в качестве вывода вбраузер:

TOP
hello, world
hello again, world
BOTTOM

В результате я получаю:

TOP
hello, world
BOTTOM

В моем эксперименте вы заметите, что я добавил еще один скрипт между тем, что мы определяем как A иC. Назовите это, я полагаю;это показывает, что если вы динамически добавляете сценарий с текстом (т.е. не удаленный сценарий), который содержит document.write, doc.write в A 'будет работать.

Кроме того, dummy.js и CSSфайлы приходят из JSFiddle.Они не преступники;Я могу воссоздать эту проблему в любом месте.

Вещи, которые я знаю:

  • , если вы замените C на IMG, проблема не будет
  • , если вы замените C наIFRAME, нет проблемы
  • , если вы переместите A после C, нет проблемы

Сейчас:

Возможно, естьсовершенно веская причина для этого.Должно быть, так как все браузеры, в которых я тестировал, ведут себя примерно одинаково.Что я хотел бы знать, почему?Любые объяснения, подсказки и / или указатели приветствуются.Даже намеки, как "Это в спецификации, тупой :)" У меня толстая кожа;Я могу справиться с этим.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я ненавижу document.write.Я не намерен поддерживать или поддерживать его использование каким-либо образом.Однако, учитывая характер моей работы, я должен сейчас обойти это, и эта странность возникла на мне.Таким образом, я хотел бы избегать комментариев вдоль линии «Вы не должны использовать document.write», потому что это, я уже верю в:)

Ответы [ 2 ]

5 голосов
/ 21 марта 2012

Выполнение document.write из асинхронных загружаемых сценариев не поддерживается в HTML5, в частности, потому, что это очень сложно: у вас нет способа узнать, будет ли ваш сценарий выполняться до или после DOMContentLoaded. См. http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#ignore-destructive-writes-counter и http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-write шаг 2 и http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#execute-the-script-block шаг 3. Дело в том, что при работе над записью, если скрипт превосходит гонку до DOMContentLoaded, но игнорируется, если проиграл гонку было бы довольно странно и приводило к тому, что страницы иногда работали, а иногда не зависели от условий сети

0 голосов
/ 21 марта 2012

SEC7112: скрипт из https://raw.github.com/gist/2141272/1a6bf0111ce10d55e628e3736a9d381d82e8a780/external-with-docwrite.js был заблокирован из-за несоответствия типов MIME

Это ваша проблема.Сценарий передается как text/plain, что не является допустимым типом MIME для JavaScript.

...