Да, это единственный способ заставить скрипт загружаться при разборе страницы. Или, по крайней мере, единственный способ, которым я хотел бы верить, работал хорошо кросс-браузерно.
Если бы ваш сценарий был таким, я мог бы увидеть ваше мышление:
<script>
var x = document.createElement("script");
x.src = "console.log.1.js";
x.async = false;
x.defer = false;
document.body.appendChild(x);
</script>
<script><!-- note the new script element -->
console.log("2");
console.log("3");
</script>
... потому что в теории, когда синтаксический анализатор достигает элемента script
, он приостанавливает все (потому что могут быть операторы document.write
) и вызывает уровень JavaScript. Так что вы можете подумать, ну, добавление элемента script
в конец body
в этот момент вставит его между ними.
Но добавление элемента script
через appendChild
принципиально отличается, это по своей природе асинхронная операция (ваш код продолжается, пока загружается скрипт, что не имеет место с элементами script
в запрете разметки атрибуты defer
или async
). Я не могу указать ни на одну спецификацию, чтобы сказать почему, но поведение, которое вы видите, это именно то, что я ожидал. Обработка script
элементов, встроенных в разметку, немного особенная.
Мы видим, что проблема заключается в загрузке & mdash; по крайней мере, в Chrome & mdash; сравнивая результат с использованием элемента script
с содержимым inline .
Использование внешнего файла ( живая копия | живой источник ):
<script>
console.log("before");
(function() {
var s = document.createElement("script");
s.src = "http://jsbin.com/avatiw"; // Logs the word "during"
document.body.appendChild(s);
})();
</script>
<script>
console.log("after");
</script>
Результат:
before
after
during
Использование встроенного скрипта ( живая копия | живой источник - обратите внимание, что я не пытался сделать этот кросс-браузер, он работает в Chrome и Firefox, так как они поддерживают свойство text
для script
элементов):
<script>
console.log("before");
(function() {
var s = document.createElement("script");
s.text = "console.log('during');";
document.body.appendChild(s);
})();
</script>
<script>
console.log("after");
</script>
Выход:
before
during
after