Встраивать JavaScript в тело HTML - плохая практика?


85

Команда, над которой я работаю, приобрела привычку использовать <script>теги в случайных местах тела наших HTML-страниц. Например:

<html>
    <head></head>
    <body>
        <div id="some-div">
            <script type="text/javascript">//some javascript here</script>
        </div>
    </body>
</html>

Я такого раньше не видел. Кажется, он работает в нескольких браузерах, которые я тестировал. Но насколько я знаю, размещать теги скриптов в подобных местах недопустимо.

Я ошибся? Насколько плохо, что мы помещаем теги сценария в теги div, как это? Есть ли какие-либо проблемы совместимости браузера, о которых мне следует знать?


1
Это document.writesпроисходит там, или нет особой причины быть там, где он есть?
Мартин Смит

8
Скрипт законно встречается в любом месте тела. В этом нет ничего плохого. Это имеет свои последствия (время, ремонтопригодность, смешение кода и макета, личные предпочтения), но в остальном это нормально.
Tomalak

@earlz - посмотри мой ответ, почему это плохо. просто пытаюсь спасти здесь жизнь. и я прав.
Джейсон

Ответы:


89

Это совершенно верно.

Вы бы не хотели помещать туда большие блоки кода, смешанные в разметке (лучше использовать внешние скрипты), но это может быть полезно для:

  • добавить дополнительную информацию привязки для прогрессивного улучшения (где эти данные трудно вписать в имя класса или другой подход к сокрытию расширенной информации в атрибутах); или же

  • где необходимо как можно быстрее запустить улучшение по сценарию (а не ждать загрузки окна / готовности документа). Примером этого может служить автофокус, который может раздражать, если сработать слишком поздно.

Возможно, вы думаете об <style>элементах, которые нельзя использовать <body>(хотя большинство браузеров, тем не менее, это допускают).


12
+1 за автофокус; иногда у меня медленное соединение, и неинтересно быть где-то еще (в худшем случае: набирать пароль), когда меня возвращают в первое поле.
Марсель Корпель,

1
Однако встраивание JS может быть полезно, когда есть только одна страница, и для уменьшения количества запросов на сервер. Та же история и со встроенным CSS. Но обычно лучше разделить код javascript и css в отдельные файлы, чтобы сократить время загрузки страницы (с использованием действительного заголовка кеша) при использовании шаблона с теми же требованиями javascript и css.
Codebeat 05

17

На самом деле это довольно распространенное явление. Например , код отслеживания Google Analytics использует именно такой синтаксис:

<script type="text/javascript">
  var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
  document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

Если этого достаточно для Google ...


37
-1 - то, что Google делает это, не означает, что это хорошая практика. Обычный! = Хорошо.
Джейсон

3
В любом случае Google Analytics слишком запутан, и использование ими JavaScript для отслеживания на самом деле является хорошим примером чрезмерной разработки.
Esko

Кроме того, они рекомендуют размещать скрипт внизу страницы, а не в середине, где скрипты должны быть размещены, если вам нужно их разместить. НЕ в заголовке, куда их обычно помещают
Джейсон

2
Не по теме: меня всегда раздражало ненужное и странное использование Google unescape, учитывая, что escape/ unescapeIs Evil (и это \x3Cбыло бы намного проще).
bob

3
@Keltex: Код не является недействительным, однако утверждение, что это хорошая практика только потому, что некоторые люди его используют, не является допустимым аргументом.
Матти Вирккунен

4

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


4

Как отметили несколько человек, это действительно так, это работает и широко используется.

Наилучшая практика с точки зрения семантики (или, по крайней мере, используемой для рекомендаций) заключается в размещении тегов сценария внутри заголовка.

Более современные передовые методы, учитывающие производительность, рекомендуют размещать теги сценария (внешние и встроенные) в правом нижнем углу перед тегом body, чтобы разметка полностью отображалась до выполнения любого кода JavaScript.

Для упрощения понимания и поддержки кода рекомендуется использовать «ненавязчивый JavaScript», когда код находится во внешнем файле и связывает события с DOM (ненавязчивый JavaScript Google).

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


3

Я предпочитаю помещать ссылки на внешние скрипты в голову, а скрипты, запускающие и инициализирующие виджеты и тому подобное, в тело.

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

<div id="foo">
  <script type="text/javascript">
    document.getElementById("foo")... // do something to it
  </script>
</div>

IE не понравится ваша страница. Старые версии IE выдавали очень загадочные сообщения об ошибках для этой или даже целую страницу, но IE8, кажется, выдает описательные сообщения об ошибках.

Если вы убедитесь, что ваши скрипты обращаются только к DOM, доступ к которому безопасен, я не считаю плохим помещать элементы скрипта в тело. Фактически, IMHO, размещение сценариев, которые инициализируют виджеты после связанных элементов, может быть более читаемым, чем размещение всего в одном месте (и я считаю, что это также может заставить их запускаться раньше, что заставляет вещи меньше прыгать по мере загрузки страницы).


3

Это действительно так!

Вы можете использовать:

<script type="text/javascript">
    //<![CDATA[

    // Some JavaScript code that perfectly validates in the W3C validator

    //]]>
</script>

Я не думаю, что вы можете сказать, является ли это плохой практикой в ​​целом. Вы должны рассказать по делу. Но несомненно, что хорошо иметь весь код JavaScript в одном месте. Это немного беспорядочно, если у вас есть небольшие фрагменты кода JavaScript по всему HTML-файлу.


2
это вообще плохая практика.
Джейсон

хорошо, просто прочтите ваш пост, полезно знать. Я все равно никогда этого не делаю, но никогда не думал, что это может привести к зависанию вашего браузера ... ... как это происходит?
meo

1
Любой JavaScript может повесить ваш браузер (иногда я все еще получаю эти окна предупреждений в Firefox с опциями «Прервать скрипт» и «Продолжить скрипт»).
Марсель Корпель

это правда, любой JS может повесить ваш браузер. однако, если вы собираетесь его повесить (obv никогда не рекомендуется), лучше сделать это после того, как страница будет полностью отрисована с содержимым и пользователь сможет начать чтение / взаимодействие со страницей. Причина, по которой JS зависает в вашем браузере, заключается в том, что он работает синхронно, а это означает, что браузер должен дождаться полного выполнения JS, прежде чем продолжить рендеринг, поскольку он не знает, что будет делать JS. Пока он ожидает, он не рендерится, что делает вид, что он завис.
Джейсон

Не используйте эту штуку CDATA - это ерунда. Только парсеры, проверяющие XML, понимают разделы CDATA, поэтому, если ваши страницы обслуживаются в формате HTML, функциональной разницы нет. Однако, если ваши страницы обслуживаются в формате XML, то перед открывающим тегом будет отображаться «//».
Brothercake

2

Я такого раньше не видел. Кажется, он работает в нескольких браузерах, которые я тестировал. Но насколько я знаю, размещать теги скриптов в подобных местах недопустимо.

Это действительно, но не рекомендуется (или не рекомендуется).

Я ошибся? Насколько плохо, что мы помещаем теги сценария в теги div, как это? Есть ли какие-либо проблемы совместимости браузера, о которых мне следует знать?

Нет проблем с размещением <script>под любыми другими элементами (но он должен быть внутри <head>или <body>). Также нет проблем с совместимостью браузеров, однако встраивание JS-скриптов на веб-страницы имеет серьезные недостатки (как и почему они считаются плохими) :

  1. Добавляет вес страницы
  2. Сложность (или, вероятно, невозможность) минификации
  3. Невозможно перенести или использовать для других страниц
  4. Не может быть кэширован (необходимо загружать каждый раз при загрузке страницы)
  5. Нет разделения проблем (сложнее поддерживать)

2

Однако это также хорошо, что вы знаете, что код JavaScript, необходимый для раздела HTML, будет там для этого. Вместо того, чтобы утверждать и создавать какое-то включение в верхней части файла.

Поэтому вместо того, чтобы «если вы собираетесь использовать этот HTML, убедитесь, что вы импортируете xyz.js», вы можете просто включить HTML и покончить с ним.

Так что это не обязательно ужасное зло. Возможно, не очень впечатляюще, но и не совсем ужасно. Это вроде как зависит от намерения.


2

См. Передовой опыт в пользовательском интерфейсе Yahoo: http://developer.yahoo.com/performance/rules.html (JavaScript внизу страницы)


большой +1! Так много ответов, но ни один из них не упоминает, что скрипты в HEAD могут блокировать другие элементы (например, изображения! Которые могут испортить макет при медленном соединении)
Дэвид Дж

1

Это определенно законно; Я видел это, например, на нескольких страницах здесь, на Exforsys .

Теперь это обучающий сайт, демонстрирующий основы HTML и JavaScript, так что в этом контексте он совершенно понятен. Однако я бы не хотел видеть это в производственном коде для чего-то большего, чем просто пару операторов. Не видя, что вы заменили, // Some JavaScript code hereя бы не хотел комментировать.

Однако с этим не должно быть проблем с браузером.


1

Допускается добавление <script> body, но Internet Explorer это очень не нравится. Поэтому, чтобы быть в большей безопасности, убедитесь, что ваши скрипты находятся внутри тега <head>.

Это действительно создавало хаос (особенно для Internet Explorer) в проекте, над которым мы работаем.


1

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

Я бы не сказал, что есть что-то плохое в том, чтобы делать это, когда АБСОЛЮТНО НЕОБХОДИМО (если это в блоке CDATA), но помимо этого я бы рекомендовал вашей команде использовать библиотеку сценариев, такую ​​как Prototype или jQuery, и сохранить сценарии, внешние по отношению к странице. Обычно это чище, и библиотеки иногда заставляют немного чистить код, чего, я готов поспорить, в настоящее время не происходит.

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


1

Это один из многих-многих передовых методов, направленных как на повышение производительности, так и на улучшение вашего подхода к программированию.

В конечном итоге в веб-разработке самое важное - выпустить продукт!



0

Часто указываемая рекомендация о том, что скрипты должны храниться в заголовке, заключается в том, чтобы гарантировать, что скрипт загружается до его вызова. Это проблема только для определенных обработчиков событий. Для других типов скриптов это не имеет значения, а для некоторых типов (например, document.write) это не имеет никакого смысла.


0

Если у вас есть редактор, который может одновременно обрабатывать синтаксис HTML и JavaScript. И если вам нравится сначала прочитать несколько строк HTML, а затем JavaScript cpde ... конечно. Действуй.


Похоже на Visual Studio и бритвенные представления, которые могут справиться и с тем, и с другим. В некоторых случаях это может быть довольно удобно (весь код нужно редактировать в одном месте). Конечно, слишком много javascript в представлении может затруднить чтение и понимание кода, а также существует проблема раздувания выходного html.
jahu

0

Несколько вещей:

  1. Это полностью корректный код.
  2. Это совершенно не рекомендуется.

Это значительно замедляет загрузку вашей страницы, так как код JavaScript должен выполняться до того, как любая остальная часть страницы сможет отобразиться. Если вы много работаете с этим кодом JavaScript, ваш браузер может зависнуть. Вы должны попытаться (когда это возможно) загрузить код JavaScript динамически и в конце страницы (желательно перед</body> тегом).

Купите и прочтите High Performance JavaScript . Это изменит способ написания кода JavaScript.


3
Не мои отрицательные голоса, но когда я думаю, что Yahoo, я думаю YAHOO.util.Event.addListener, не эффективный / краткий javascript. Я бы не стал читать книгу и относиться к ней как к евангелию, иногда у вас должен быть javascript на самой странице, например, динамически отображаемая переменная, чего нельзя сделать во внешнем .js.
Ник Крейвер

2
ты читал книгу? если бы вы знали, вы бы знали, что он учит методам оптимизации. такие вещи, как YAHOO.xx.xx.xxкэшируются локально. иногда да, отображать переменную на странице можно, но обычно это можно сделать извне, если вы просто установите скрытое входное значение с сервера. но я сказал, что это не рекомендуется, не неправильно . Кроме того, автор статьи Николас Закас знает свое дерьмо, независимо от того, кто его работодатель.
Джейсон

2
«Динамическая загрузка» и «загрузка в конце страницы» - это разные вещи, и маловероятно, что есть какой-либо прирост производительности от их использования. "Вы читали книгу?" и «Я прав» - тоже не лучший способ начать конструктивный разговор. Также на исходный вопрос можно ответить так: «потому что он в конечном итоге подавляет IE», поскольку некоторые операции поддерживаются только в том случае, если скрипт является прямым потомком тела.
Начо Колома
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.