7

In the given html, how can I tell that a dom element is a standard html component defined by the browser or a web component defined in a script (by an author):

<div></div>
<custom-web-component></custom-web-component>

I know that there is no way to check programmatically if a web component was already registered. Also they are both considered HTMLElement. Is there a way to check that a dom node is standard html or custom web component? Let's asume I get the dom element using querySelector()

Supersharp
  • 29,002
  • 9
  • 92
  • 134
Adrian Moisa
  • 3,923
  • 7
  • 41
  • 66

3 Answers3

15

To detect if a DOM element is a registred Custom Element, you should use customElements.get().

If the element is not yet registered or if it's a standard HTML element, the method will return undefined.

If it's a registered Custom Element it will return its class.

customElements.define( 'custom-element', class extends HTMLElement {} )

console.log( customElements.get( 'custom-element' ) )
console.log( customElements.get( 'p' ) )
console.log( customElements.get( 'fake-element' ) )
console.log( customElements.get( 'font-face' ) )
<custom-element></custom-element>
<fake-element></fake-element>
<p></p>
<font-face></font-face>
Supersharp
  • 29,002
  • 9
  • 92
  • 134
8

A custom element's name is required to contain a -, whereas an HTML-defined element will not. So:

if (theElement.tagName.includes("-")) {
    // It's custom
} else {
    // It isn't
}

(Or .indexOf("-") != -1 for older browsers that don't have String#includes yet.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 3
    Thank you for the quick answer. I've been doing some follow-up reading and I learned that there are a few [SVG elements](https://stackoverflow.com/a/22545622/1903781) that break the rule. It's easy to check for this scenario. – Adrian Moisa Dec 10 '17 at 10:35
2

You should consider that there are custom tag names that may not be defined custom elements. e.g. document.createElement('custom-tagname').

If you want to check that it's actually an instance of a registered custom-element you can use instanceof:

function isDefinedCustomElement(node) {
    if (node.tagName.includes("-")) {
        return false;
    }
    const customElementClass = window.customElements.get(node.tagName.toLowerCase());
    return customElementClass && node instanceof customElementClass;
}
pmoleri
  • 4,238
  • 1
  • 15
  • 25