Document.head, document.body для прикрепления скриптов
Я часто использовал и видел рекомендуемые структуры доступа с правами доступа, например, для динамического добавления контента на страницы:
loader = document.createElement('script');
loader.src = "myurl.js";
document.getElementsByTagName('head')[0].appendChild(loader);
Теперь, случайно, я нахожу, что это работает в Google Chrome:
document.head.appendChild(loader);
Немного больше исследований, и я считаю, что это работает, по-видимому, кросс-браузер:
document.body.appendChild(loader);
Итак, мой основной вопрос: есть ли какие-либо причины, по которым я не должен прикреплять элементы к ТЕЛО, как это?
Также, как вы думаете, document.head
станет более широко поддерживаться?
Ответы
Ответ 1
Я не вижу причин, почему на практике было бы важно вставить элементы <script>
в элемент <head>
или <body>
. Теоретически, я полагаю, что это хорошо, если бы DOM времени выполнения напоминал потенциальный статический.
Что касается document.head
, его часть HTML5 и, по-видимому, уже реализована в последних сборках всех основных браузеров (см. http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-document-head).
Ответ 2
document.body
является частью спецификации DOM, я не вижу смысла, почему бы не использовать его. Но имейте в виду:
В документах с содержимым возвращается элемент, а в документах фреймов возвращается этот самый внешний элемент.
(из https://developer.mozilla.org/en/DOM/document.body)
document.head
в настоящее время не определен ни в одной спецификации DOM (по-видимому, я ошибался, см. ответ Дэниела), поэтому обычно вам следует избегать его использования.
Ответ 3
См. мой ответ по аналогичному вопросу для более тщательного сравнения параметров. (т.е. раздел / script.appendChild против раздела/script.insertBefore)
Ответ 4
Я попытался реализовать этот код и столкнулся с небольшими проблемами, поэтому хотел поделиться своим опытом.
Сначала я попробовал это:
<script>
loader = document.createElement('script');
loader.src = "script.js";
document.getElementsByTagName('head')[0].appendChild(loader);
</script>
И в файле script.js у меня был код, например:
// This javascript tries to include a special css doc in the html header if windowsize is smaller than my normal conditions.
winWidth = document.etElementById() ? document.body.clientWidth : window.innerWidth;
if(winWidth <= 1280) { document.write('<link rel="stylesheet" type="text/css" href="style/screen_less_1280x.css">'); }
Проблема в том, что когда я все это сделал, код не сработает. В то время как выполнял, как только я заменил загрузчик script следующим образом:
<script src="script.js"></script>
Это работает для меня, поэтому проблема решена на данный момент, но я хотел бы понять разницу между этими двумя подходами. Почему один работал, а не другой?
Что еще в script.js У меня также есть код, например:
function OpenVideo(VideoSrcURL) {
window.location.href="#OpenModal";
document.getElementsByTagName('video')[0].src=VideoSrcURL;
document.getElementsByTagName('video')[0].play();}
И этот код работает отлично, независимо от того, каким образом я запускаю script в своем html файле.
Итак, мое изменение размера окна script не работает, но материал для видео делает. Поэтому мне интересно, имеет ли разница в поведении объект "document"...? Возможно, "document" ссылается на файл script.js вместо html файла.
Я не знаю. Думаю, я должен поделиться этой проблемой, если она применима ко всем остальным.
Приветствия.
Ответ 5
Ответы, данные до сих пор, сосредоточены на двух разных аспектах и оба очень полезны.
Если для вас требуется переносимость, в документах, не принадлежащих вам, где вы не можете контролировать согласованность DOM, может быть полезно проверить наличие элемента, к которому необходимо добавить скрипт; таким образом, это будет работать и тогда, когда раздел HEAD не был явно создан:
var script = document.createElement('script');
var parent = document.getElementsByTagName('head').item(0) || document.documentElement;
parent.appendChild(script);
Помимо политики CORS и других легко обнаруживаемых логических ошибок, я не вижу случаев, когда эта задача манипуляции DOM не будет выполнена, поэтому проверка на document.body
как запасной вариант не является необходимой с моей точки зрения.
Как отмечали и другие пользователи, на момент публикации вопроса document.head
не получал широкой поддержки, поскольку это спецификация HTML5, а document.body
- именно поэтому вы видели, как последний работает на всех браузерах.
Таким образом, вы можете получить ГОЛОВУ с:
document.head || document.getElementsByTagName('head').item(0)
но я не считаю это очень полезным, так как последний никогда не ошибется и представляет собой читаемый и стандартный запрос DOM, если только вы не обнаружите, что document.head
быстрее с точки зрения производительности.
Еще одно возможное преимущество, которое я вижу в этой форме, - это переход кода со старого JavaScript на более современный HTML5-совместимый код, краткий и более читаемый.
Если совместимость необходима, вы можете использовать приемы, принятые библиотеками, для которых переносимость обязательна (например, решения от Google, Yandex и других):
var parent = document.getElementsByTagName('head')[0] || document.documentElement.firstChild;
parent.appendChild(script);
Таким образом, в невероятном случае элемент HEAD не существует, в то время как BODY (или другой элемент) существует, вы обязательно добавите скрипт к нему.
Я также добавляю полезный бит: HTTP-запрос источника сценария отправляется из браузера, когда атрибут src
установлен и добавлен в DOM. Независимо от того, в каком порядке выполняются эти два условия, последнее из этих двух событий вызывает отправку HTTP-запроса.