Чи погана практика вбудовувати JavaScript у тіло HTML?


84

Команда, над якою я працюю, узяла звичку використовувати <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
Сценарії законно допускаються в будь-якому місці тіла. У цьому немає нічого поганого. Це має свої наслідки (терміни, ремонтопридатність, змішування коду та верстки, особисті переваги), але в іншому випадку це нормально.
Томалак

@earlz - див. мою відповідь, чому це погано. просто намагаюся врятувати життя тут. і я маю рацію.
Джейсон

Відповіді:


88

Це цілком справедливо.

Ви не хотіли б розміщувати там великі великі блоки коду, змішані там у розмітці (краще використовувати зовнішні сценарії), але це може бути корисно для:

  • додати додаткову інформацію про прив’язку для поступового вдосконалення (де ці дані складно вписати в назву класу або інший підхід до приховування розширеної інформації в атрибутах); або

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

Можливо, ви думаєте про <style>елементи, які заборонені <body>(хоча більшість браузерів це дозволяють).


12
+1 для автофокусу; іноді я маю повільний зв’язок, і мені не цікаво опинятися десь ще (в гіршому випадку: введення пароля), коли мене повертають у перше поле.
Марсель Корпель

1
Однак вбудовування JS може бути корисним, коли є лише одна сторінка, і зменшити кількість пошуків на сервері. Те саме, що до вбудованого CSS. Але зазвичай краще відокремлювати код javascript та css у відокремлених файлах, щоб зменшити час завантаження сторінки (за допомогою дійсного заголовка кешу), коли використовується шаблон із однаковими вимогами щодо javascript та css.
Codebeat

17

Насправді, це досить часто. Наприклад , код відстеження аналітики Google використовує саме такий синтаксис:

<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 для відстеження насправді є хорошим прикладом надмірної техніки.
Еско

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

2
Окрім поза темами: мене завжди дратує непотрібне та химерне використання Google unescape, враховуючи, що escape/ unescapeIs Evil (і це \x3Cбуло б набагато простішим способом зробити це).
bobince

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

4

Він дійсний, і, залежно від вашого серверного фреймворку та природи коду, іноді його дуже важко уникнути.


4

Як згадували кілька людей, він дійсний, працює і широко використовується.

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

Більш сучасні найкращі практики, що враховують продуктивність, рекомендують розміщувати теги скриптів (зовнішні та вбудовані) внизу праворуч перед тегом тіла, щоб дозволити розмітку повністю відтворюватися перед виконанням будь-якого коду JavaScript.

Для полегшення розуміння та обслуговування коду рекомендується використовувати "ненав’язливий JavaScript", коли код знаходиться у зовнішньому файлі та пов’язує події з DOM (Google ненав’язливий JavaScript).

Одним з випадків, коли корисно мати вбудований 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, тоді він відтворить "//" перед початковим тегом.
браткейк

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.
джаху

0

Кілька речей:

  1. Це повністю дійсний код.
  2. Це абсолютно не рекомендується.

Це значно уповільнює завантаження вашої сторінки, оскільки код JavaScript повинен виконуватися, перш ніж будь-яка інша частина сторінки зможе відтворити. Якщо ви багато працюєте з цим кодом JavaScript, ваш браузер може зависнути. Спробуйте (коли це можливо) завантажувати код JavaScript динамічно та в кінці сторінки (бажано перед </body>тегом).

Придбайте та прочитайте високопродуктивний JavaScript . Це змінить спосіб написання коду JavaScript.


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

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

2
"Динамічне завантаження" та "завантаження в кінці сторінки" - це різні речі, і вкрай малоймовірно, що від їх використання можна збільшити продуктивність. "Ви читали книгу?" і "я маю рацію" - теж не найкращий спосіб розпочати конструктивну розмову. Також на оригінальне запитання можна відповісти "оскільки це врешті-решт задихається в IE", оскільки деякі операції підтримуються лише в тому випадку, якщо скрипт є безпосереднім потомком тіла.
Nacho Coloma
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.