Документ JavaScript.напишите Порядок выполнения встроенного скрипта

StackOverflow https://stackoverflow.com/questions/94141

Вопрос

У меня есть следующий скрипт, где первый и третий document.writeline являются статичными и генерируется второй:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

Firefox и Chrome будут отображать до того, как, во время и после, в то время как Internet Explorer сначала показывает во время и только тогда это проявляется до того, как и после.

Я сталкивался с статья , в которой говорится то, что я не первый, кто сталкивается с этим, но вряд ли от этого мне становится легче.

Кто-нибудь знает, как я могу установить порядок детерминированным во всех браузерах или взломать IE, чтобы он работал так, как это делают все другие вменяемые браузеры?

Предостережения:Фрагмент кода представляет собой очень простое воспроизведение.Он генерируется на сервере, и второй скрипт - это единственное, что меняется.Это длинный скрипт, и причина, по которой до и после него есть два скрипта, заключается в том, что браузер будет кэшировать их, а динамическая часть кода будет как можно меньше.Он также может появляться много раз на одной и той же странице с разным сгенерированным кодом.

Это было полезно?

Решение 2

Я нашел ответ, который мне больше по душе:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script defer language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>");
document.write("<script defer language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

Это отложит загрузку обоих во время и после до тех пор, пока страница не завершит загрузку.

Я думаю, это все, что я могу сделать.Надеюсь, кто-нибудь сможет дать лучший ответ.

Другие советы

Нет, это поведение Internet Explorer.

Если вы подключаете скрипты динамически, IE, Firefox и Chrome будут загружать скрипты асинхронным образом.

Firefox и Chrome будут ждать, пока вернутся все асинхронные запросы, а затем выполнят скрипты в том порядке, в котором они прикреплены в DOM, но IE выполнит скрипты в том порядке, в котором они возвращаются по проводам.

Поскольку для "извлечения" предупреждения требуется меньше времени, чем для внешнего файла javascript, это, вероятно, объясняет поведение, которое вы видите.

От Кристоффера Хенрикссона сообщение на тему асинхронной загрузки скрипта:

В этом сценарии IE и Firefox загрузят оба скрипта, но Internet Explorer также выполнит их в порядке, в котором они завершат загрузку тогда как Firefox загружает их асинхронно, но все равно выполняет в порядке, в котором они прикреплены в ДОМ.

В Internet Explorer это означает, что ваши скрипты не могут зависеть друг от друга, поскольку порядок выполнения будет меняться в зависимости от сетевого трафика, кэшей и т.д.

Рассмотрите возможность использования загрузчика Javascript.Это позволит вам указать зависимости скриптов и порядок выполнения, одновременно загружая ваши скрипты асинхронно для повышения скорости, а также сглаживая некоторые различия в работе браузера.

Это довольно хороший обзор некоторых из них: Необходимый JavaScript:пятерка лучших загрузчиков скриптов.

Я использовал как RequireJS, так и LABjs.На мой взгляд, LABjs немного менее самоуверенна.

Слайды 25/26 из эта презентация расскажите о характеристиках различных методов вставки скриптов.Это говорит о том, что IE - единственный браузер, который будет выполнять эти скрипты по порядку.Все остальные браузеры будут выполнять их в том порядке, в котором они завершат загрузку.Даже IE не будет выполнять их по порядку, если у одного или нескольких есть встроенный js вместо src.

Одним из предложенных методов является вставка нового элемента DOM:

var se1 = document.createElement('script');
se1.src = 'a.js';

var se2 = document.createElement('script');
se2.src = 'b.js';

var se3 = document.createElement('script');
se3.src = 'c.js';

var head = document.getElementsByTagName('head')[0]
head.appendChild(se1);
head.appendChild(se2);
head.appendChild(se3);

Чтобы сгенерировать второй раздел скрипта, вы могли бы использовать скрипт для генерации этого содержимого и передачи параметров:

se2.src = 'generateScript.php?params=' + someParam;

Редактировать:Несмотря на то, что говорится в статье, которую я разместил, мое тестирование показывает, что большинство браузеров будут выполнять ваш document.write скрипты по порядку, если у каждого из них есть src, поэтому, хотя я думаю, что описанный выше метод предпочтительнее, вы могли бы сделать и это:

<script language="javascript" type="text/javascript">
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

ОТРЕДАКТИРУЙТЕ ЕЩЕ РАЗ (ответ на комментарии к себе и другим):Вы уже создаете скрипт на своей странице.Все, что вы делаете, может быть перенесено в другой серверный скрипт, который генерирует тот же блок кода.Если вам нужны параметры на вашей странице, то передайте их скрипту в строке запроса.

Кроме того, вы можете использовать этот же метод, если, как вы предлагаете, вы генерируете встроенный скрипт несколько раз:

<script language="javascript" type="text/javascript">
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params1 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params2 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params3 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

Однако это начинает выглядеть так, как будто вы подходите к этому неправильно.Если вы генерируете большой блок кода несколько раз, то вам, вероятно, следует заменить его одной js-функцией и вызывать ее с другими параметрами...

Хорошо ... во время...

// During.js
during[fish]();

после...

// After.js
alert("After");
fish++

HTML

<!-- some html -->
<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>");
</script>
<!-- some other html -->
<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>");
</script>

Однако я склонен согласиться с тем, как это начинает пахнуть.В частности, почему вы не могли закодировать "during" в динамически созданный js-файл и вставить это?

Обратите внимание, что динамически сгенерированный скрипт идет следующим образом внутри функция в второй документируйте.пишите.
Протестировано в FF2, IE7

Вы можете принудительно выполнить secuential, определив события "onload" (или аналогичные) в сценариях и введя следующее событие в функцию event.Это нетривиально, но есть множество примеров, вот один из них.

http://www.phpied.com/javascript-include-ready-onload/

Я думаю, что популярные библиотеки, такие как jQuery или prototype, могут помочь в этом.

Код для предоставления:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript'>function callGeneratedContent() { alert('during'); }<\x2Fscript>");
document.write("<script language='javascript' type='text/javascript' src='before.js'><\x2Fscript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'><\x2Fscript>");
</script>

В before.js:

alert("Before");
callGeneratedContent();

В after.js:

alert("After");

Вы должны поместить сгенерированную строку первой, иначе FF будет жаловаться, потому что она выполняется before.js до просмотра определения функции.

Как насчет этого:

<script>
document.write("<script src='before.js'><\/script>");
</script>

<script >
document.write("<script>alert('during');<\/script>");
</script>

<script>
document.write("<script src='after.js'><\/script>");
</script>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top