3

How can I test if an element is self-enclosed in JavaScript? So, here is an example of an element that is self enclosed:

<input type="text" value="I'm self-enclosed.">

And here is an example of an element which isn't:

<div>I'm not self-enclosed.</div>

How can I differentiate between them in JavaScript?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
undefined
  • 3,949
  • 4
  • 26
  • 38
  • Technically, you didn't self-close the first example. It should be `` – j08691 Jan 05 '15 at 19:52
  • 1
    @j08691 - the slash is not required in HTML5 – adeneo Jan 05 '15 at 19:55
  • What's the purpose? What if the `div` has no content? –  Jan 05 '15 at 19:55
  • 3
    Out of curiosity, why would you want to know such a thing? – Krimson Jan 05 '15 at 19:55
  • "HTML5, however, uses HTML parsing syntax, making the /> unnecessary for void elements. It is, however, valid to use it." - [Source](http://tiffanybbrown.com/2011/03/23/html5-does-not-allow-self-closing-tags/). Also, the function would still be valid and in most browsers "/>" is automatically replaced with ">". But thanks for pointing that out! :) – undefined Jan 05 '15 at 19:55
  • Dupe: http://stackoverflow.com/questions/22046163/check-if-an-element-is-closed-using-a-discrete-tag-with-javascript – Marc B Jan 05 '15 at 19:55
  • On the other hand, libraries like jQuery uses a regex and a list of void elements to check if the element is self-closing, which seems like a more reliable way to do it than checking the innerHTML – adeneo Jan 05 '15 at 19:58
  • @Krimson I was making an HTML Typer (that is, like a regular typer, but smart enough to type P intead of <....etc and I needed to differentiate between them because if the typer finds a self-enclosed tag like an image, it should display it automatically and not "type it". – undefined Jan 05 '15 at 19:58
  • Better use a [reqular expression](http://stackoverflow.com/a/1732454/1348195). – Benjamin Gruenbaum Jan 05 '15 at 19:59
  • why do you ask something that you've been able to solve yourself in less than 4 min? – acontell Jan 05 '15 at 20:00
  • 1
    @acontell - posting both the question and the answer is fine, as long as it something useful ? – adeneo Jan 05 '15 at 20:00
  • 1
    @acontell To save someone 4 minutes. – undefined Jan 05 '15 at 20:01
  • @adeneo If it's something that takes time to solve, I can see the point, if it's something solved that quickly, I fail to do so. – acontell Jan 05 '15 at 20:02
  • @acontell it's not just fine, it's encouraged. We'd have a better Stack Overflow if people posted answers to more common problems they were stuck on. – Benjamin Gruenbaum Jan 05 '15 at 20:02
  • “Self-enclosed” is not an HTML term, or a defined term anywhere. If you mean elements that lack a separate end tag, you should say that. You should also specify whether you are referring the actual markup used for the element in HTML source or in serialized formt (which one?) as generated by a browser. – Jukka K. Korpela Jan 05 '15 at 21:25

2 Answers2

4

Answer & Demo

You can detect if an element is self-enclosed via the following function, here is a JSFiddle with the demo.

HTML

<div>False</div><br>
<input type="text" value="True"/><br>

Two simple HTMLElement's, the first one is not self enclosed, the second one is.

JavaScript

function isSelfEnclosed(element) {
    var elem = document.createElement( element.tagName );
    return elem.outerHTML.indexOf( "><" ) == -1;
}

isSelfEnclosed( div ) -> False, assuming div is the div element.

isSelfEnclosed( input ) -> True, assuming input is the input element.

Explanation

We make a new element after the element's tag name, and we check if it's .outerHTML has "><" in it.

Note

I made this self-answered question because the only other answer I found wasn't exactly bulletproof. Anyway it's a simple function with a simple purpose, hope it helps somebody!

Updates

  • Updated incorrect code using cloneNode( true ) instead of just cloneNode() (17:01p.m 05/01/15)
  • Updated function to more efficiently handle the problem (17:09p.m 05/01/15)
Community
  • 1
  • 1
undefined
  • 3,949
  • 4
  • 26
  • 38
  • 1
    Why pass `true` to `.cloneNode()` only to clear its content a moment later with `.innerHTML = ""`? –  Jan 05 '15 at 19:57
4

I'd rather check the tagName against a list of known void elements, than rely on innerHTML returning something with >< in it

function isSelfEnclosed(element) {
    return ['area', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param'].indexOf(element.tagName.toLowerCase()) != -1;
}

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • Hahahaha that's another choice! Of course if a new void element is added to the documentation, you would have to update the function, but that isn't very likely, thanks for answering :) – undefined Jan 05 '15 at 20:06
  • @Rou - In that case, you would have to update the doctype and probably a lot more as well. – adeneo Jan 05 '15 at 20:07
  • I agree with this. Relying on HTML serialization seems shaky. –  Jan 05 '15 at 20:07
  • What about custom void elements? (Are those even allowed? I haven't found anything in the spec) – Benjamin Gruenbaum Jan 05 '15 at 20:11
  • Also - if you write them in uppercase you could avoid the toLowerCase check since `tagName` is always uppercase. – Benjamin Gruenbaum Jan 05 '15 at 20:12
  • @squint I've updated the function for it's max. efficiency, it's impossible that it would fail now, as it check's the tagName, inspired by your response (but I think better) :) – undefined Jan 05 '15 at 20:12
  • @BenjaminGruenbaum I do not know if custom void element's are a thing, but in my updated answer the function uses `document.createElement` to check for enclosing, so if it's a registered custom element, it should be able to handle it accordingly :) – undefined Jan 05 '15 at 20:14
  • @Rou Yes, I understand why _your_ solution works for this case I was wondering about adeneo's solution which is why I commented on it. – Benjamin Gruenbaum Jan 05 '15 at 20:15
  • @Rou: It could fail with an error if a non-element is passed, but you may want failure in that case. –  Jan 05 '15 at 20:15
  • @BenjaminGruenbaum - in HTML tagNames are always in uppercase, in XML, it depends. I always add `toLowerCase` just as an old habit, checking for uppercase strings would work just as well today where XHTML and XML isn't an issue anymore. – adeneo Jan 05 '15 at 20:17
  • @BenjaminGruenbaum - The new thing now, is that you can create any element tagName you want, but those have an ending tag, I don't think you can create custom void elements, but I could be wrong – adeneo Jan 05 '15 at 20:18
  • @adeneo just read the custom elements spec - pretty sure there is no way to create custom vote elements - so a vote well earned. – Benjamin Gruenbaum Jan 05 '15 at 20:19
  • And looking at [**MDN**](https://developer.mozilla.org/en-US/docs/Web/API/Document.registerElement), it looks like custom elements can't be self-closing, and have to adhere to certain standards etc. – adeneo Jan 05 '15 at 20:20
  • @BenjaminGruenbaum - posted at the same time, didn't see you there – adeneo Jan 05 '15 at 20:24