Почему не работают самозакрывающиеся элементы скрипта?

По какой причине браузеры неправильно распознают:

<script src="foobar.js" /> <!-- self-closing script element -->

Только это признается:

<script src="foobar.js"></script>

Это нарушает концепцию поддержки XHTML?

Примечание: это утверждение верно по крайней мере для всех IE (6-8 бета 2).

Ответы

Ответ 1

Спецификация XHTML 1 гласит:

С .3. Минимизация элементов и содержание пустых элементов

Для данного пустого экземпляра элемента, модель содержимого которого не является EMPTY (например, пустой заголовок или абзац), не используйте свернутую форму (например, используйте <p> </p>, а не <p />).

DTD XHTML определяет элементы сценария как:

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>

Ответ 2

Чтобы добавить к тому, что сказали Брэд и Сквадетт, самозакрывающийся синтаксис XML <script /> на самом деле является правильным XML, но для того, чтобы он работал на практике, вашему веб-серверу также необходимо отправлять ваши документы как правильно сформированные. XML с миметипом XML, например, application/xhtml+xml в заголовке HTTP Content-Type (а не как text/html).

Однако отправка mimetype XML приведет к тому, что ваши страницы не будут анализироваться IE7, который любит только text/html.

С w3:

Таким образом, 'application/xhtml + xml' СЛЕДУЕТ использовать для семьи XHTML документы и использование "text/html" ДОЛЖЕН быть ограничен HTML-совместимым XHTML 1.0 документы. 'Приложение /XML' и 'text/xml' МОЖЕТ также использоваться, но когда это уместно, 'application/xhtml + xml' ДОЛЖЕН использоваться а не эти общие носители XML типы.

Я ломал голову над этим несколько месяцев назад, и единственным работоспособным (совместимым с FF3+ и IE7) решением было использование старого синтаксиса <script></script> с text/html (синтаксис HTML + mimetype HTML).

Если ваш сервер отправляет тип text/html в своих заголовках HTTP, даже если XHTML-документы правильно сформированы иным образом, FF3+ будет использовать режим HTML-рендеринга, что означает, что <script /> не будет работать (это изменение, ранее Firefox был меньше). строги).

Это будет происходить независимо от того, какие возни с метаэлементами http-equiv, прологом XML или документом внутри вашего документа - Firefox разветвляется, как только он получает заголовок text/html, который определяет, будет ли парсер HTML или XML выглядеть внутри документа, и Анализатор HTML не понимает <script />.

Ответ 3

Если кому-то интересно, окончательная причина в том, что HTML изначально был диалектом SGML, который является странным старшим братом XML. В земле SGML элементы могут быть определены в DTD как самозакрывающиеся (например, BR, HR, INPUT), неявно закрываемые (например, P, LI, TD) или явно закрываемые (например, TABLE, DIV, SCRIPT). XML, конечно, не имеет понятия об этом.

Парсеры тег-супа, используемые современными браузерами, развились из этого наследия, хотя их модель синтаксического анализа больше не является чистым SGML. И, конечно, ваш тщательно созданный XHTML рассматривается как плохо написанный SGML-вдохновленный тег-суп, если вы не отправите его с типом mime XML. Это также почему...

<p><div>hello</div></p>

... интерпретируется браузером как:

<p></p><div>hello</div><p></p>

... что является рецептом для милой неясной ошибки, которая может привести вас в ярость, когда вы пытаетесь кодировать против DOM.

Ответ 4

Другие ответили "как" и процитировали спец. Вот реальная история "почему нет <script/>", после многих часов копания в отчетах об ошибках и списках рассылки.


HTML 4

HTML 4 основан на SGML.

SGML имеет несколько ярлыков shorttags, таких как <BR//, <B>text</>, <B/text/ или <OL<LI>item</LI</OL>. XML принимает первую форму, переопределяет окончание как ">" (SGML гибкий), так что он становится <BR/>.

Тем не менее, HTML не улучшился, поэтому <SCRIPT/> должно означать <SCRIPT>>.
(Да, символ ">" должен быть частью содержимого, а тег все еще не закрыт.)

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

По сути, все "рабочие" самозавершающиеся теги являются тегами с запрещенным конечным тегом в технически несовместимых синтаксических анализаторах и фактически являются недействительными. Это был W3C, который придумал этот хак, чтобы помочь перейти на XHTML, сделав его HTML-совместимым.

И конечный тег <script> не запрещен.

"Самозакрывающийся" тег - это взлом в HTML 4 и бессмысленный.


HTML 5

HTML5 имеет пять типов тегов, и только теги 'void' и 'foreign' могут быть самозакрывающимися.

Поскольку <script> не является пустым (оно может иметь контент) и не является чужим (например, MathML или SVG), <script> не может быть самозакрытым, независимо от того, как вы его используете.

Но почему? Разве они не могут расценивать это как чужое, делать особый случай или что-то в этом роде?

HTML 5 стремится быть обратно совместимым с реализациями HTML 4 и XHTML 1. Он не основан на SGML или XML; его синтаксис в основном связан с документированием и объединением реализаций. (Вот почему <br/> <hr/> и т.д. Являются действительными HTML 5, несмотря на то, что являются недействительными HTML4.)

Самозакрывающийся <script> является одним из тегов, в которых реализации различаются. Он раньше работал в Chrome, Safari, и Opera; насколько мне известно, он никогда не работал в Internet Explorer или Firefox.

Это обсуждалось, когда HTML 5 разрабатывался и был отклонен, поскольку он нарушает совместимость браузера browser compatibility. Веб-страницы, которые автоматически закрывают тег сценария, могут отображаться некорректно (если вообще) в старых браузерах. Были другие предложения, но они также не могут решить проблему совместимости.

После того, как черновик был выпущен, WebKit обновил синтаксический анализатор, чтобы он соответствовал требованиям.

Самозакрытие <script> не происходит в HTML 5 из-за обратной совместимости с HTML 4 и XHTML 1.


XHTML 1/XHTML 5

Когда действительно используется как XHTML, <script/> действительно закрыт, как утверждают другие ответы.

За исключением того, что спецификация говорит, что это должно было работать, когда служило HTML:

Документы XHTML... могут быть помечены типом интернет-медиа "text/html" [RFC2854], поскольку они совместимы с большинством браузеров HTML.

Итак, что случилось?

Люди попросили Mozilla разрешить разрешить Firefox анализировать документы, соответствующие XHTML, независимо от указанного заголовка содержимого (известного как анализатор содержимого). Это позволило бы самозакрывающимся сценариям, и в любом случае необходим анализ содержимого was necessary, поскольку веб-хостеры не были достаточно зрелыми, чтобы обслуживать правильный заголовок; IE был хорош в этом.

Если первая война браузеров first browser war не закончилась IE 6, возможно, XHTML также был в списке. Но это закончилось. И IE 6 имеет проблему с XHTML. Фактически IE не поддерживал правильный тип MIME вообще, заставляя всех использовать text/html для XHTML, потому что IE удерживал основную долю рынка в течение целого десятилетия.

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

Наконец, оказывается, что W3C не означал, что XHTML может быть сниффином: документ - это и HTML, и XHTML, и правила Content-Type. Можно сказать, что они твердо придерживались "просто следуйте нашим спецификациям" и игнорируя то, что было практичным. Ошибка в том, что продолжил в более поздних версиях XHTML.

В любом случае, это решение решило вопрос для Firefox. Прошло 7 лет, прежде чем Chrome родился; не было другого значимого браузера. Так было решено.

Только указание типа документа не вызывает синтаксический анализ XML из-за следующих спецификаций.

Ответ 5

Internet Explorer 8 и более ранние версии не поддерживают синтаксический анализ XHTML. Даже если вы используете объявление XML и/или XTYTML-тип, старый IE все еще анализирует документ как обычный HTML. И в простом HTML самозакрывающийся синтаксис не поддерживается. Конечная косая черта просто игнорируется, вы должны использовать явный закрывающий тег.

Даже браузеры с поддержкой синтаксического анализа XHTML, такие как IE 9 и более поздние версии, все равно будут анализировать документ как HTML, если вы не будете обслуживать документ с помощью тип содержимого XML. Но в этом случае старый IE вообще не отобразит документ!

Ответ 6

Вышеупомянутые люди уже в значительной степени объяснили проблему, но одна вещь, которая может прояснить ситуацию, заключается в том, что, хотя люди используют <br/> и так все время в документах HTML, любая / в такой позиции в основном игнорируется, и только используется при попытке сделать что-то как разбираемое как XML и HTML. Попробуйте, например, <p/>foo</p>, и вы получите обычный абзац.

Ответ 7

Сам закрывающий тег script не будет работать, потому что тег script может содержать встроенный код, а HTML недостаточно умный, чтобы включать или отключать эту функцию на основе наличия атрибута.

С другой стороны, HTML имеет отличный тег для включения ссылки на внешние ресурсы: тег <link>, и это может быть самозакрывающиеся. Он уже использовал для включения таблиц стилей, RSS и Atom каналы, канонические URI и всевозможные другие лакомства. Почему нет JavaScript?

Если вы хотите, чтобы тег script был включен, вы не можете сделать это, как я уже сказал, но есть альтернатива, хотя и не умная. Вы можете использовать тег self close link и ссылку на свой JavaScript, указав ему тип текста /javascript и rel как script, что-то вроде ниже:

<link type="text/javascript" rel ="script" href="/path/tp/javascript" />

Ответ 8

В отличие от XML и XHTML, HTML не знает о самозакрывающемся синтаксисе. Браузеры, которые интерпретируют XHTML как HTML, не знают, что символ / указывает, что тег должен быть самозакрывающимся; вместо этого они интерпретируют его как пустой атрибут, и парсер по-прежнему считает, что тег "открыт".

Так же, как <script defer> рассматривается как <script defer="defer">, <script /> рассматривается как <script /="/">.

Ответ 9

Internet Explorer 8 и старше не поддерживают правильный тип MIME для XHTML, application/xhtml+xml. Если вы используете XHTML как text/html, который вам нужен для этих более старых версий Internet Explorer, чтобы сделать что-либо, он будет интерпретироваться как HTML 4.01. Вы можете использовать только короткий синтаксис с любым элементом, который позволяет исключить закрывающий тег. См. Спецификация HTML 4.01.

"Краткая форма" XML интерпретируется как атрибут с именем /, который (потому что нет знака равенства) интерпретируется как имеющий неявное значение "/". Это строго неверно в HTML 4.01 - незадекларированные атрибуты не разрешены, но браузеры будут игнорировать его.

IE9 и более поздняя версия поддерживают XHTML 5 с application/xhtml+xml.

Ответ 10

Это потому, что SCRIPT TAG не является ЭЛЕМЕНТОМ VOID.

В HTML-документе - ЭЛЕМЕНТЫ VOID не вообще не нужен "закрывающий тег" !

В xhtml все является общим, поэтому всем им нужно завершение, например. "закрывающий тег" ; Включение br, простой разрыв строки, как <br></br> или его сокращение <br />.

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

В принципе, инструкция Semantic Termination, например "закрывающий тег" , необходима только для обработки инструкций, семантика которых не может быть прервана последующим тегом. Например:

<H1> семантика не может быть прервана следующим <P>, потому что она не переносит достаточно своей собственной семантики для переопределения и, следовательно, завершает предыдущий набор команд H1. Хотя он сможет сломать поток в новую строку абзаца, он не "достаточно силен", чтобы переопределить текущий размер шрифта и стиль строки-высоты, заливающий поток, то есть утечку из H1 ( потому что у Р нет).

Вот как и почему была выработана сигнализация "/" (прекращения).

Общее завершение описания без описания Тег, подобный < />, хватило бы для любого отдельного падения с встреченного каскада, например: <H1>Title< />, но это не всегда так, потому что мы также хотим иметь возможность "вложенности", множественная промежуточная маркировка потока: разбивается на торренты перед обертыванием/падением на другой каскад. Как следствие, общий терминатор, такой как < />, не сможет определить цель прекращения действия. Например: <b> жирный <i> жирный курсив < /> курсив </> нормальный. Несомненно, не получило бы нашего намерения правильно и, скорее всего, интерпретировало бы его как жирным жирным шрифтом жирным шрифтом.

Вот как родилось понятие оболочки, т.е. контейнера. (Эти понятия настолько похожи, что невозможно различить, и иногда один и тот же элемент может иметь оба. <H1> одновременно является оберткой и контейнером, а <b> - только семантическая оболочка). Нам нужен простой, без семантического контейнера. И, конечно же, пришло изобретение элемента DIV.

Элемент DIV на самом деле является 2BR-контейнером. Конечно, приход CSS сделал всю ситуацию более странной, чем в противном случае, и вызвал большую путаницу со многими великими последствиями - косвенно!

Потому что с помощью CSS вы можете легко переопределить собственный pre & после поведения BR нового изобретенного DIV, его часто называют "контейнером" ничего не делать ". Что, естественно, неправильно! DIV являются блочными элементами и будут изначально ломать линию потока как до, так и после концевой сигнализации. Вскоре WEB начал страдать от страницы DIV-itis. Большинство из них все еще есть.

Приход CSS с возможностью полного переопределения и полного переопределения собственного поведения любого HTML-тега каким-то образом позволил запутать и размыть весь смысл существования HTML...

Внезапно все теги HTML выглядели как устаревшие, они были разрушены, лишены всего их первоначального значения, личности и цели. Каким-то образом у вас создалось впечатление, что они больше не нужны. Высказывание: для всего представления данных достаточно одного тега контейнера-обертки. Просто добавьте необходимые атрибуты. Почему бы не использовать значащие теги; Создайте имена тегов Inventor, когда вы идете, и пусть CSS беспокоит остальных.

Вот как родился xhtml и, конечно, великий тупой, так дорого заплаченный новыми посетителями и искаженное видение того, что есть, и какая чертова цель всего этого. W3C перешел от World Wide Web к тому, что пошло не так, товарищи?!!

Целью HTML является передать значимые данные получателю.

Чтобы предоставить информацию.

Формальная часть предназначена только для ясности доставки информации. xhtml не дает ни малейшего внимания информации. - Для этого информация абсолютно бесполезна.

Самое главное в этом вопросе - знать и уметь понимать, что xhtml - это не просто версия некоторого расширенного HTML, xhtml - совершенно другой зверь; основания; и поэтому разумно держать их в отдельности.

Ответ 11

Разница между "истинным XHTML", "faux XHTML" и HTML, а также важностью типа MIME, отправленного сервером, была уже хорошо описанный здесь. Если вы хотите попробовать прямо сейчас, вот простой отредактированный фрагмент с предварительным просмотром в реальном времени, включая самозакрытый тег сценария для браузеров:

  div {display: flex; }
div + div {flex-direction: column; }Код>
  <div> Тип Mime: <label> < input type =  "radio"  onchange =  "t.onkeyup()"  id = "x" checked name =  "mime"  > приложение /XHTML  + XML </& этикетки GT;
<label> < input type =  "radio"  onchange =  "t.onkeyup()"  name =  "mime"  > Текст /HTML  </& этикетки GT; </дел >
<div> < textarea id = "t" rows = "4" 
OnKeyUp = "i.src= 'данные:' + (x.checked 'приложение/XHTML + XML': 'текст/html') + '' + encodeURIComponent (t.value)" 
<? xml version = "1.0"? >
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" 
[<! ENTITY x "true XHTML" >] >] >
< html xmlns = "http://www.w3.org/1999/xhtml" >
& Л; тело >
 < р >
   < span id = "greet" swapto = "Hello" > Hell, NO: (</span> & x;.
   < script src= "data: text/javascript, (g = document.getElementById('greet')). innerText = g.getAttribute('swapto')" />
   Приятно познакомиться!
   <! -
     Предыдущий текстовый узел и все последующее содержимое попадают в содержимое элемента SCRIPT в текстовом /html  режиме, поэтому не отображаются. Поскольку никакой тег конца сценария не найден, скрипт не запускается в text/html
   - >
 </р >
</тело >
</HTML> </& TextArea GT;

< iframe id = "i" height = "80" > </iframe>

< & сценарий GT; t.onkeyup() </& сценарий GT;
</DIV>код>