2012-02-01 3 views
6

Следующий код [jsfiddle] ...Пользовательские самозакрывающиеся/непарные теги в HTML?

var div = document.createElement("div"); 
div.innerHTML = "<foo>This is a <bar /> test. <br> Another test.</foo>"; 
alert(div.innerHTML); 

... показывает эту разобранную структуру:

<foo>This is a <bar> test. <br> Another test.</bar></foo> 

т.е. браузер знает, что <br> не имеет закрывающий тег, но так как <bar> неизвестный тег в браузере он предполагает, что ему нужен закрывающий тег.

Я знаю, что (солидус) синтаксис /> игнорируется в HTML5 и недействителен в HTML4, но в любом случае хотел бы научить каким-то образом, что браузер <bar> не нужен закрывающий тег, и я могу опустить. Возможно ли это?

Да, я пытаюсь (временно) неправильно использовать код HTML для пользовательских тегов, и у меня есть свои особые причины для этого. В конце концов, браузеры должны игнорировать неизвестные теги и относиться к ним так же, как к неидентифицированным встроенным тегам, поэтому я не должен ломать что-либо, поскольку я могу убедиться, что имена тегов никогда не будут использоваться в реальных стандартах HTML.

+1

Вы можете использовать нижний предел, но, пожалуйста, добавьте комментарий, объясняющий причину ... –

ответ

5

Вы должны были бы использовать Object.defineProperty на HTMLElement.prototype переопределить сеттер innerHTML и добытчика с вашей собственной реализации innerHTML, которая рассматривает элементы, которые вы хотите, как void. Посмотрите here на то, как по умолчанию реализуется innerHTML и парсер HTML.

Обратите внимание, что Firefox отстой в наследовании, когда дело доходит до определения элементов на HTMLElement.prototype, где он фильтрует до HTMLDivElement, например. В Opera все должно хорошо работать.

Другими словами, какие элементы являются недействительными, зависит от анализатора HTML. Парсер следует this list, а innerHTML использует те же правила в основном.

Иными словами, если вы не хотите создавать свою собственную реализацию innerHTML в JS, вы, вероятно, должны просто забыть об этом.

Вы можете использовать live DOM viewer, хотя и показывать другим, как анализируется определенная разметка. Тогда вы, вероятно, заметите, что те же конечные теги неявно закрывают открытый элемент.

У меня есть устаревший внутренний HTTML getter (не setter хотя) код here, который использует список элементов void. Это может дать вам некоторые идеи. Но написать сложную реализацию сеттера может быть сложнее.

С другой стороны, если вы используете createElement() и appendChild() и т. Д. Вместо innerHTML, вам не стоит беспокоиться об этом, а родной getHTML-получатель выводит неизвестные элементы с концевыми тегами.

Примечание, хотя, вы можете рассматривать неизвестный элемент в XML и использовать XMLSerializer() и DomParser(), чтобы сделать вещи:

var x = document.createElement("test"); 
var serializer = new XMLSerializer(); 
alert(serializer.serializeToString(x)); 
var parser = new DOMParser(); 
var doc = parser.parseFromString("<test/>", "application/xml"); 
var div = document.createElement("div"); 
div.appendChild(document.importNode(doc.documentElement, true)); 
alert(serializer.serializeToString(div)); 

Это не совсем то, что вы хотите, но то, что вы можете играть с. (Протестируйте, что в Opera вместо Firefox, чтобы увидеть разницу с атрибутами xmlns. Также обратите внимание, что Chrome не работает, как Opera и Firefox.)

+0

Спасибо за все полезные ссылки.Я использую innerHTML по двум причинам: во-первых, потому что это довольно быстрый и толерантный парсер. Во-вторых, поскольку моя цель состоит не в том, чтобы полагаться на innerHTML, но и на использование существующего поддерева DOM. Это означает, что сам браузер должен принимать новые теги void, если это вообще возможно. --- В качестве примечания, мне интересно, как можно добавить новые теги ** void **, скажем, в стандарт HTML6 +, поскольку они, по-видимому, путают все HTML5-парсеры ... –

+0

@UdoG Добавлено с чем вы можете играть. – Shadow2531

Смежные вопросы