Зачем расколоть тэг <script> при записи его с помощью document.write()?
Почему некоторые сайты (или рекламодатели, которые предоставляют код JavaScript javascript) используют метод разделения тегов <script>
и/или </script>
в пределах вызовов document.write()
?
Я заметил, что Amazon делает это также, например:
<script type='text/javascript'>
if (typeof window['jQuery'] == 'undefined') document.write('<scr'+'ipt type="text/javascript" src="http://z-ecx.images-amazon.com/images/G/01/javascripts/lib/jquery/jquery-1.2.6.pack._V265113567_.js"></sc'+'ript>');
</script>
Ответы
Ответ 1
</script>
должен быть разбит, потому что в противном случае он закончил бы закрытие блока <script></script>
слишком рано. Действительно, он должен быть разделен между <
и /
, поскольку предполагается, что блок script (согласно SGML) будет завершен любым концом -tag open (ETAGO) (т.е. </
):
Хотя элементы STYLE и script используют CDATA для своей модели данных, для этих элементов CDATA должен обрабатываться по-разному с помощью пользовательских агентов. Разметка и объекты должны рассматриваться как необработанные и передаваться в приложение как есть. Первое вхождение символьной последовательности "</
" (разделитель открытого конца тега) рассматривается как завершение конца содержимого элемента. В действительных документах это будет конечным тегом для элемента.
Однако на практике браузеры заканчивают разбор блока CDATA script на фактическом теге </script>
close.
В XHTML нет такой специальной обработки для блоков script, поэтому любой символ <
(или &
) внутри них должен быть &escaped;
как в любом другом элементе. Однако браузеры, которые анализируют XHTML как HTML старой школы, будут запутаны. Существуют обходные пути с использованием блоков CDATA, но проще всего избегать использования этих символов без привязки. Лучшим способом записи элемента script из script, который работает на любом из парсеров, будет:
<script type="text/javascript">
document.write('\x3Cscript type="text/javascript" src="foo.js">\x3C/script>');
</script>
Ответ 2
Вот еще один вариант, который я использовал, когда хочу сгенерировать тег script inline (поэтому он выполняется немедленно), не требуя каких-либо форм экранов:
<script>
var script = document.createElement('script');
script.src = '/path/to/script.js';
document.write(script.outerHTML);
</script>
(Примечание: вопреки большинству примеров в сети, я не устанавливаю type="text/javascript"
ни в теге, ни в приложении, ни в сгенерированном: браузер не имеет этого по умолчанию, поэтому он избыточен, но и не повредит, если вы не согласны).
Ответ 3
Я думаю, что это не позволяет интерпретатору HTML-браузера интерпретировать <script> , и, главным образом, </script> в качестве закрывающего тега фактического script, однако я не думаю, что использование document.write - отличная идея для оценки блоков script, почему бы не использовать DOM...
var newScript = document.createElement("script");
...
Ответ 4
Решение, которое Бобинс написал, отлично работает для меня. Я хотел предложить альтернативный метод для будущих посетителей:
if (typeof(jQuery) == 'undefined') {
(function() {
var sct = document.createElement('script');
sct.src = ('https:' == document.location.protocol ? 'https' : 'http') +
'://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js';
sct.type = 'text/javascript';
sct.async = 'true';
var domel = document.getElementsByTagName('script')[0];
domel.parentNode.insertBefore(sct, domel);
})();
}
В этом примере я включил условную нагрузку для jQuery, чтобы продемонстрировать пример использования. Надеюсь, что это полезно для кого-то!
Ответ 5
</script>
внутри строки Javascript litteral интерпретируется парсером HTML как закрывающий тег, вызывая неожиданное поведение (см. пример в JSFiddle).
Чтобы этого избежать, вы можете разместить свой javascript между комментариями (этот стиль кодирования был обычной практикой, когда Javascript плохо поддерживался среди браузеров). Это будет работать (см. Пример в JSFiddle):
<script type="text/javascript">
<!--
if (jQuery === undefined) {
document.write('<script type="text/javascript" src="http://z-ecx.images-amazon.com/images/G/01/javascripts/lib/jquery/jquery-1.2.6.pack._V265113567_.js"></script>');
}
// -->
</script>
... но, честно говоря, использование document.write
- это не то, что я считаю лучшей практикой. Почему бы не манипулировать DOM напрямую?
<script type="text/javascript">
<!--
if (jQuery === undefined) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', 'http://z-ecx.images-amazon.com/images/G/01/javascripts/lib/jquery/jquery-1.2.6.pack._V265113567_.js');
document.body.appendChild(script);
}
// -->
</script>