Почему не работают самозакрывающиеся элементы script?
Проблема: Некорректное распознавание самозакрывающегося тега <script>
браузерами
Подскажите, в чем причина того, что браузеры не распознают корректно следующий код:
<script src="foobar.js" /> <!-- самозакрывающийся элемент script -->
Правильно распознается только следующий вариант:
<script src="foobar.js"></script>
Влияет ли это на концепцию поддержки XHTML?
Примечание: Данное утверждение верно для всех версий Internet Explorer (6-8 бета 2).
5 ответ(ов)
В случае, если кого-то это заинтересует, основная причина заключается в том, что HTML изначально был диалектом SGML, который является странным старшим братом XML. В мире SGML элементы могут быть указаны в DTD как самозакрывающиеся (например, BR, HR, INPUT), неявно закрывающиеся (например, P, LI, TD) или явно закрывающиеся (например, TABLE, DIV, SCRIPT). В XML, разумеется, нет такого понятия.
Парсеры tag-soup, используемые современными браузерами, развились из этого наследия, хотя их модель парсинга больше не является чистым SGML. И, конечно, ваш тщательно созданный XHTML обрабатывается как плохо написанный SGML-подобный tag-soup, если вы не отправите его с типом MIME XML. Это также объясняет, почему...
<p><div>hello</div></p>
...интерпретируется браузером как:
<p></p><div>hello</div><p></p>
...что является источником неприятного скрытого бага, который может ввести вас в замешательство, пока вы пытаетесь кодировать против DOM.
Люди выше уже достаточно подробно объяснили проблему, но одно, что может прояснить ситуацию, это то, что, хотя в HTML-документах часто используются <br/>
и подобные теги, любой /
в такой позиции по сути игнорируется. Он используется лишь для того, чтобы сделать код как парсируемым в XML, так и в HTML. Например, попробуйте <p/>foo</p>
– вы получите обычный параграф.
В отличие от XML и XHTML, HTML не поддерживает синтаксис самозакрывающихся тегов. Браузеры, которые интерпретируют XHTML как HTML, не понимают, что символ /
указывает на то, что тег должен быть самозакрывающимся. Вместо этого они воспринимают его как пустой атрибут, и парсер по-прежнему считает тег "открытым".
Так же, как тег <script defer>
рассматривается как <script defer="defer">
, тег <script />
трактуется как <script /="/">
.
Это потому, что тег SCRIPT не является пустым элементом.
В HTML-документе ПУСТЫЕ ЭЛЕМЕНТЫ не требуют закрывающего тега вообще!
В XHTML все является общим, поэтому каждому элементу необходима терминация, например, закрывающий тег; включая br, простой перенос строки, как <br></br>
или его сокращение <br />
.
Однако элемент script никогда не является пустым или параметрическим элементом, потому что тег script прежде всего является инструкцией для браузера, а не декларацией описания данных.
Принципиально, семантическая инструкция о терминации, например, закрывающий тег, нужна только для обработчиков инструкций, семантику которых нельзя завершить последующим тегом. Например:
Семантика <H1>
не может быть завершена следующим <P>
, потому что она не содержит достаточно своей собственной семантики, чтобы переопределить и, следовательно, завершить предыдущий набор инструкций H1. Хотя <P>
может разбить поток на новый абзац, она не "достаточно сильна", чтобы переопределить текущий размер шрифта и стиль высоты строки, проливающегося от H1 (потому что P этого не имеет).
Таким образом и была изобретена сигнализация терминации в виде "/".
Универсальный безописательный тег терминации, такой как < />
, мог бы подойти для любого отдельного разрыва в каскаде, например: <H1>Название< />
, но это не всегда так, потому что мы также хотим иметь возможность "вкладывать" несколько промежуточных тегов в поток: разделять на потоки перед оборачиванием / падением на другой каскад. Следовательно, универсальный терминатор, такой как < />
, не смог бы определить цель свойства для завершения. Например: <b>
жирный <i>
жирный-курсив < />
курсив </>
нормальный. Это, безусловно, не удалось бы прочитать правильно и, скорее всего, было бы интерпретировано как жирный жирный-курсив жирный нормальный.
Таким образом, появилась концепция обертки, то есть контейнера. (Эти понятия так схожи, что их невозможно отличить, и иногда один и тот же элемент может относиться к обоим. <H1>
является как оберткой, так и контейнером одновременно, тогда как <B>
— это всего лишь семантическая обертка). Нам потребуется простой, без семантики контейнер. И, конечно, была изобретена DIV-обертка.
Элемент DIV по сути является контейнером 2BR. Конечно, появление CSS сделало всю ситуацию более запутанной, чем это было бы в противном случае, и вызвало большую путаницу с множеством серьезных последствий - косвенно!
Поскольку с помощью CSS вы могли легко переопределить нативное поведение BR до и после вновь созданного DIV, его часто называют "контейнером, ничего не делающим". Что, конечно, неправильно! DIV является блочным элементом и по своей сути разрывает поток как до, так и после сигнала окончания. Вскоре WEB начал страдать от "DIV-итиса". Большинство из них все еще страдают.
Появление CSS с его возможностями полностью переопределить и полностью изменить нативное поведение любого HTML-тега как-то смогло запутать и стереть смысл существования HTML...
Вдруг все HTML-теги стали казаться устаревшими, они были испорчены, лишены всех их оригинальных значений, идентичности и цели. Казалось, что они больше не нужны. Утверждая: один тег-контейнер обертки будет достаточно для всей презентации данных. Просто добавьте необходимые атрибуты. Почему бы не иметь значимые теги вместо этого; изобретайте названия тегов по мере необходимости и дайте CSS позаботиться о остальном.
Так родился XHTML и, конечно, пришел великий удар, который так дорого обошелся новичкам и создал искаженное представление о том, что есть что, и в чем же смысл всего этого. W3C прошло от World Wide Web к "Что пошло не так, товарищи?!!"
Цель HTML — передавать значимую информацию человеческому получателю.
Чтобы донести информацию.
Формальная часть существует лишь для того, чтобы содействовать ясности передачи информации. XHTML не учитывает информацию ни в малейшей степени. Для него информация совершенно не важна.
Самое важное в этом вопросе — понимать и осознавать, что XHTML не является просто версией некоторого расширенного HTML, XHTML — это совершенно другой зверь; с нуля; и поэтому мудро держать их отдельно.
Современный ответ заключается в том, что тег обозначен как обязательный именно таким образом.
Пропуск тегов: Никаких, как начальный, так и конечный теги обязательны.
Как определить, виден ли элемент DOM в текущей области просмотра?
Как выбрать элемент по имени с помощью jQuery?
jQuery: Получение Выбранного Значения Из Выпадающего Списка
Прокрутка до низа div?
Как получить фактическую ширину и высоту HTML-элемента?