Custom self-closing / unpaired tags in HTML?

The following code [ jsfiddle ] ...

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

... shows this structure being analyzed:

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

i.e. the browser knows that <br> does not have a closing tag, but since <bar> is an unknown tag for the browser, it assumes that it needs a closed tag.

I know that the /> (solidus) syntax is ignored in HTML5 and not valid in HTML4, but in any case I would like to somehow teach the browser that the <bar> does not need an end tag, and I can omit it. Is it possible?

Yes, I am trying (temporarily) to incorrectly use the HTML for custom tags, and I have my own special reasons for this. In the end, browsers should ignore unknown tags and treat them the same way as unidentified embedded tags, so I shouldn't break anything because I can make sure that tag names will never be used in real HTML standards.

+6
source share
1 answer

You will need to use Object.defineProperty in HTMLElement.prototype to override setter and getter innerHTML with its own innerHTML which treats the elements you want as void . Take a look here for how innerHTML and the HTML parser are implemented by default.

Note that Firefox sucks in inheritance when it comes to defining material on HTMLElement.prototype, where it filters, for example, on HTMLDivElement. In Opera, everything should work well.

In other words, which elements are invalid depends on the HTML parser. The parser follows this list and innerHTML uses the same rules basically.

So, if you do not want to create your own implementation of innerHTML in JS, you should probably just forget about it.

You can use the live DOM viewer to show others how specific markup is parsed. Then you will probably notice that the same end tags implicitly close the open item.

I have an obsolete innerHTML getter (not setter though) code here that uses a list of void elements. This may give you some ideas. But writing a setter implementation can be harder.

On the other hand, if you use createElement () and appendChild (), etc. instead of innerHTML, you don’t have to worry about this, and the native innerHTML getter displays unknown elements with end tags.

Note that you can treat the unknown element as xml and use XMLSerializer () and DOMParser () to do the following:

 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)); 

This is not exactly what you want, but what you can play with. (Check that in Opera instead of Firefox, to see the difference with the xmlns attributes. Also note that Chrome does not work, like Opera and Firefox.)

+5
source

Source: https://habr.com/ru/post/907381/


All Articles