Using JavaScript and according to the HTML standard, how do I acplish this? don't know where to start coding a function where isSingleClosing('input')
must return true (note the />
) while isSingleClosing('div')
returns false for example. self or single closing tag looks like this <tag/>
and non single closing <tag></tag>
Using JavaScript and according to the HTML standard, how do I acplish this? don't know where to start coding a function where isSingleClosing('input')
must return true (note the />
) while isSingleClosing('div')
returns false for example. self or single closing tag looks like this <tag/>
and non single closing <tag></tag>
- Do you already have some code? where are you stuck? – Razieltje Commented May 27, 2015 at 14:03
- make an array of tags that are self closing. when the function is called, loop through the array and see if the passed value is in the array. If it is, return true. If it is not, return false. – CrayonViolent Commented May 27, 2015 at 14:04
- 1 Not really. This answer to a similar question notes the self-closing tag list that jQuery uses internally: stackoverflow./a/2292440/1324 – Paul Roub Commented May 27, 2015 at 14:04
3 Answers
Reset to default 6The most consistent and easiest would be to keep a list of self-closing elements
var elems = ['area', 'base', 'br', 'col', 'mand', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
function isSingleClosing(elem) {
return elems.indexOf( elem.tagName.toLowerCase() ) !== -1;
}
Such an isSingleClosing
function would look like this:
const isSingleClosing = (tagName, ns = "http://www.w3/1999/xhtml") => {
const elem = document?.createElementNS?.(ns, tagName)
?? document.createElement(tagName);
return !(window.XMLSerializer
? new XMLSerializer().serializeToString(elem)
: elem.outerHTML).includes("></");
};
console.log("Is tag 'img' self-closing?", isSingleClosing("img"));
console.log("Is tag 'p' self-closing?", isSingleClosing("p"));
console.log("Is tag 'bgsound' self-closing?", isSingleClosing("bgsound"));
console.log("Is tag 'image' self-closing?", isSingleClosing("image"));
console.log("Is tag 'image', in namespace 'http://www.w3/2000/svg', self-closing?", isSingleClosing("image", "http://www.w3/2000/svg"));
console.log("Is tag 'animateTransform' self-closing?", isSingleClosing("animateTransform"));
console.log("Is tag 'animateTransform', in namespace 'http://www.w3/2000/svg', self-closing?", isSingleClosing("animateTransform", "http://www.w3/2000/svg"));
It creates the element based on the passed tagName
and attempts to serialize it. It then tries to find ></
in the serialization. If it’s found, it’s not a self-closing tag, so return false
, otherwise it is one, so return true
. This function easily supports different namespaces (e.g. HTML elements, SVG elements, MathML elements, etc.) using createElementNS
.
At least one of outerHTML
and XMLSerializer
is supported in virtually every browser. However, XMLSerializer
is aware of different namespaces and yields more accurate results. The code above is also written in ECMAScript 2020, which can be transpiled into something more patible for older browsers, which, in turn, don’t support all of the methods used in the code.
This only covers tags supported in the browser running this function. It will return true
for bgsound
, but false
for mand
or menuitem
which are deprecated, not standardized, or were never supported by any browser to begin with. <image>
may have some non-standard or legacy behavior where it’s recognized as a self-closing HTML element.
There’s probably no way to get all cases right in both a backward- and forward-patible way. But this is better than keeping a long list of elements up to date.
I'm interpreting this question to mean "detect whether an element is void"
Self-closing elements—i.e. XHTML—aren't really a thing anymore (JSX looks like XHTML but doesn't generally emit XHTML) and in any event the answer for XHTML is to look at the element's outerHTML for a />
).
Especially in these days of custom-elements, it's much harder to answer this question by spouting a list of built-in void elements (you can subclass void elements). I'd suggest:
function isVoid(element) {
element.append('x')
const isVoid = element.innerText === ''
// clean up after ourselves
element.childNodes[element.childNodes.length - 1].remove()
return isVoid
}
The reason for this is that void elements support the mon properties like append
, so you can't even assume a void element will have no children
or childNodes
.