How to detect unofficial tags in html?

Viewed 651

Given an HTML node, how would you tell if it bears official HTML tag or not?

<h9 id="someNodeId">hello<h9>
let node = document.getElementById("someNodeId");

In above code snippet I want h9 is not official html tag. How do I find it out programmatically using JS?

Edit: Preferably in O(1)

5 Answers

Someone already wrote a good function for this, see usage guide on GitHub.

Example:

isElementSupported("h1"); // true
isElementSupported("h9"); // false

/*
 * isElementSupported
 * Feature test HTML element support 
 * @param {String} tag
 * @return {Boolean|Undefined}
 */

(function(win){
    'use strict';       

    var toString = {}.toString;

    win.isElementSupported = function isElementSupported(tag) {
        // Return undefined if `HTMLUnknownElement` interface
        // doesn't exist
        if (!win.HTMLUnknownElement) {
            return undefined;
        }
        // Create a test element for the tag
        var element = document.createElement(tag);
        // Check for support of custom elements registered via
        // `document.registerElement`
        if (tag.indexOf('-') > -1) {
            // Registered elements have their own constructor, while unregistered
            // ones use the `HTMLElement` or `HTMLUnknownElement` (if invalid name)
            // constructor (http://stackoverflow.com/a/28210364/1070244)
            return (
                element.constructor !== window.HTMLUnknownElement &&
                element.constructor !== window.HTMLElement
            );
        }
        // Obtain the element's internal [[Class]] property, if it doesn't 
        // match the `HTMLUnknownElement` interface than it must be supported
        return toString.call(element) !== '[object HTMLUnknownElement]';
    };
    
})(this);
Tag: <input id="toCheck" type="text" value="h9"><br><br>
Is supported? <input id="result" type="text" readonly><br><br>
<input type="submit" value="Check Tag" onclick="document.getElementById('result').value= (isElementSupported(document.getElementById('toCheck').value))">

Consider the following:

const foo = document.createElement('h9');
console.log(foo.constructor.name); // HTMLUnknownElement

Note that this will not work properly for natively implemented custom elements. So barring that edge case you can easily use this method to check if a given tag is official, and unlike a hard-coded list it is future proof against new tags being added.

Note on performance:

the above check does run in O(1) time but checking every tag in the DOM will be much, much slower.

I highly recommendsanitize-html, which is a really flexible package in nodejs that sanitizes input html tags. I have only used it in nodejs applications, however I think that you can include it in a browser script.

You can add it by:

 <script type="text/javascript"  src="dist/sanitize-html.js"></script>

You can simply check whether the input HTML has changed after the sanitization, returning a boolean data type.

This is an example of sanitize-html, using the default allowed tags:

var sanitizeHtml = require('sanitize-html');

var dirty = 'some really tacky HTML';
var clean = sanitizeHtml(dirty); 

You can can get a better idea by reading the official documentation: https://www.npmjs.com/package/sanitize-html

I could create my own XML tags, and create a reference document that defines the schema for those tags. Since HTML, which comes from XML, has a standard schema of known tags, you can do this:

<h9 id='someNodeId'>Hello, world!</h9>

//list the valid tags for HTML here
let tags = ["h1","h2","h3","h4","h5","h6"];

let node = document.getElementById('someNodeId');
if( tags.find( node.tagName.toLowerCase() ) != undefined ) {
   //valid
}
else {
   //invalid
}
Related