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

1212

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

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

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

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

Разве это нарушает концепцию поддержки XHTML?

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

  • 0
    Я предполагаю, что вы говорите о правильном XHTML? пара комментариев все еще говорят о XHTML
  • 11
    Работает в Chrome и Opera
Показать ещё 9 комментариев
Теги:
internet-explorer
xhtml

11 ответов

439
Лучший ответ

Спецификация XHTML 1 говорит:

С .3. Элемент Minimization и Empty Element Content

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

XHTML DTD определяет теги script как:

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>
  • 101
    Тем не менее, «не надо» не то же самое, что «не должен». Это руководство (для совместимости, как указано в заголовке раздела), а не правило.
  • 37
    На самом деле, я не могу найти какое-либо применение для этого ограничения :) Это кажется полностью искусственным.
Показать ещё 6 комментариев
211

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

Однако отправка XML-mimetype приведет к тому, что ваши страницы не будут анализироваться 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 + HTML-тип).

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

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

  • 3
    Правильно ли тогда сделать вывод, что если вы откажетесь от поддержки IE7, отправка text / xml даст вам широкую поддержку браузера для <script />?
  • 4
    Короче говоря, <script /> будет работать, только если ваш MIME-тип страницы xhtml / xml. Для обычных текстовых / html-страниц это не сработает. И если мы попытаемся использовать MIME-тип "xhtml / xml", это нарушит совместимость IE. Подводя итог, сохраняйте спокойствие и используйте <script> ... </ script> Спасибо, Джо ;-)
Показать ещё 2 комментария
140

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

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

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

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

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

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

  • 4
    Мне любопытно. почему браузер предпочитает интерпретировать это так?
  • 27
    @AhmedAeonAxan: элемент P не может содержать элементы DIV (это недопустимый HTML), поэтому браузер неявно закрывает элемент P (определенный как «неявно закрываемый») перед открывающим тегом DIV . Однако браузеры, как правило, ведут себя по-разному в этом отношении (как они могут поступать с любым недопустимым HTML).
Показать ещё 4 комментария
129

Другие ответили "как" и цитировали спецификацию. Вот реальная история "почему нет <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 и разбивает многие сайты (к тому времени, когда браузеры были достаточно зрелы для ухода об этом), поэтому никто не реализовал shorttags и спецификацию советует против них.

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

И <script> конечный тег не является необязательным.

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

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

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


XHTML 1/XHTML 5

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

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

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

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

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

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

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

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

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

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

  • 0
    «Самозакрывающийся <script> не происходит в HTML 5 из-за обратной совместимости». - это не совсем так, поскольку ни один аспект обратной совместимости не будет нарушен, то есть написанный код будет продолжать работать в новых браузерах, которые поддерживают самозакрывающийся <script> . Настоящая причина в том, что <script> будет единственным самозакрывающимся тегом, поскольку HTML не определяет другие. Кроме того, только внешние теги могут быть самозакрывающимися, поскольку пустые теги не имеют конечного тега. Смотрите стартовые теги , шаг 6.
  • 1
    @AndyE Когда вы пишете самозакрывающийся <script>, основные браузеры в то время не думают, что он закрыт, и будут анализировать html подпоследовательности как javascript, что приведет к разрыву действительного HTML5 в этих старых браузерах. Таким образом, предложение отклонено. Это объясняется в связанном списке рассылки HTML5.
Показать ещё 10 комментариев
45

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

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

  • 9
    «IE не поддерживает синтаксический анализ XHTML». было верно для версий IE в то время, когда это было написано, но больше не верно.
  • 0
    @EricLaw, вы можете уточнить, какая версия IE исправила это? (и любые конкретные условия - например, требуется действительный тип документа)
Показать ещё 1 комментарий
25

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

23

Сам закрывающий тег 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" />
  • 4
    Мне нравится это, почему это не "умный", хотя?
  • 5
    Потому что есть предопределенный тег сценария, который точно выполняет работу по загрузке сценария. Почему вы путаете вопросы, используя что-то еще? Молотком забивает гвозди. Было бы разумно использовать обувь?
Показать ещё 1 комментарий
19

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

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

  • 32
    Это элегантное объяснение, на самом деле оно неверно. Если бы это было так, то для элемента script в DOM был бы атрибут "/". Я проверил IE, Firefox и Opera, и ни один из них не содержит такого атрибута.
  • 10
    / не является допустимым символом имени атрибута, поэтому он отбрасывается. В противном случае это объяснение довольно ясно.
Показать ещё 1 комментарий
18

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.

3

Разница между "истинным 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>код>

Вы должны увидеть Hello, true XHTML. Приятно познакомиться! ниже textarea.

Для неспособных браузеров вы можете копировать содержимое текстового поля и сохранять его в виде файла с расширением .xhtml (или .xht) (говорит Алек за этот намек).

2

Это потому, что 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 - совершенно другой зверь; основания; и поэтому разумно держать их в отдельности.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню