Почему не работают самозакрывающиеся элементы скрипта? - PullRequest
1241 голосов
/ 16 сентября 2008

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

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

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

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

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

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

Ответы [ 11 ]

454 голосов
/ 16 сентября 2008

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

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

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

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

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>
225 голосов
/ 16 сентября 2008

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

150 голосов
/ 25 июля 2010

В случае, если кому-то интересно, окончательная причина в том, что 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.

138 голосов
/ 25 февраля 2015

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


HTML 4

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

SGML имеет несколько коротких тегов , таких как <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 разрабатывался и был отклонен, потому что он ломает браузер совместимость . Веб-страницы, которые автоматически закрывают тег сценария, могут отображаться некорректно (если вообще) в старых браузерах. Были другие предложения , но они также не могут решить проблему совместимости.

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

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


XHTML 1 / XHTML 5

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

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

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

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

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

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

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

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

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

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

44 голосов
/ 16 сентября 2008

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

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

26 голосов
/ 16 сентября 2008

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

22 голосов
/ 27 октября 2012

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

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

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

<link type="text/javascript" rel ="script" href="/path/tp/javascript" />
20 голосов
/ 16 сентября 2008

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

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

18 голосов
/ 16 сентября 2008

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.

5 голосов
/ 18 августа 2017

Это потому, что TAG СКРИПТА не является пустым элементом.

В HTML-документе - VOID ELEMENTS вообще не нужен "закрывающий тег"!

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

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

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

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

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

Универсальный no-description Termination Tag, такой как < />, был бы достаточен для любого падения с встречного каскада, например: <H1>Title< />, но это не всегда так, потому что мы также хотим быть способным «вкладывать» в себя несколько промежуточных тегов потока: разбивать на потоки перед переносом / падением на другой каскад. Как следствие, общий терминатор, такой как < />, не сможет определить цель свойства для завершения. Например: <b> полужирный <i> полужирный курсив < /> курсив </> нормальный. Несомненно, не сможет правильно понять наше намерение и, скорее всего, будет интерпретировать его как жирный жирный-италлический жирный нормальный.

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

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

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

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

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

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

Назначение HTML - для потоковой передачи значимых данных человеку-получателю.

Для доставки информации.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...