Является ли использование document.write единственным возможным способом для одновременной загрузки скрипта между кросс-доменами браузера? - PullRequest
1 голос
/ 07 марта 2012

Я хочу имитировать это поведение:

<script src="console.log.1.js"></script>
<script>console.log(2)</script>
<script>console.log(3)</script>

Это выходит из системы:

1
2
3

Это не работает:

<script>
var x = document.createElement("script");
x.src = "console.log.1.js";
x.async = false;
x.defer = false;
document.body.appendChild(x);
console.log("2");
console.log("3");
</script>

Оно регистрируетout:

2
3
1

Единственный способ, который я нашел до сих пор, чтобы достичь этого:

<script>
document.write("<scrip" + "t src='console.log.1.js'></scrip" + "t>");
</script>
<script>
console.log("2");
console.log("3");
</script>

Действительно ли это единственный способ принудительной синхронной загрузки внешних скриптов во всех браузерах?Почему не работает async = false, defer = false?

ОБНОВЛЕНИЕ

К вашему сведению, если кому-то интересно, работает следующий запуск document.write (в Chrome..):

<script>
  // http://jsbin.com/avatiw logs "during"
  document.write('<scrip' + 't>console.log("before");document.write("<scrip" + "t src=\\"http://jsbin.com/avatiw\\"></scrip" + "t>");</scrip' + 't>');
  document.write('<scrip' + 't>console.log("after");</scrip' + 't>');
</script>

Работает и выходит из системы:

"before"
"during"
"after"

Ответы [ 2 ]

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

Да, это единственный способ заставить скрипт загружаться при разборе страницы. Или, по крайней мере, единственный способ, которым я хотел бы верить, работал хорошо кросс-браузерно.

Если бы ваш сценарий был таким, я мог бы увидеть ваше мышление:

<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
0 голосов
/ 07 декабря 2014

Я действительно обнаружил, что использование плагина LazyLoad идеально подходит для этого варианта использования, т.е.

if (typeof jQuery === 'undefined')
    LazyLoad.js('//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js', function() { 
        initialize(); 
    });
else
    initialize();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...