Detect if dom element is custom web component or html element
Asked Answered
B

3

8

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

Benham answered 10/12, 2017 at 9:51 Comment(1)
Please consider switching the accepted mark from my answer to Supersharp's, customElements.get is the better way to do this.Penetrant
P
7

See Supersharp's answer, customElements.get is clearly the better way to do this than the below.


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

Penetrant answered 10/12, 2017 at 10:10 Comment(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 that break the rule. It's easy to check for this scenario.Benham
<fake-element /> would fail. See Supersharp's answer.Vilberg
@Vilberg - Thanks for pointing out that answer. I've suggested the OP change the accepted mark so I can delete this, get is clearly the better way.Penetrant
M
18

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>
Matrilineage answered 10/12, 2017 at 21:28 Comment(1)
Thank you for the hint. Really useful!Benham
P
7

See Supersharp's answer, customElements.get is clearly the better way to do this than the below.


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

Penetrant answered 10/12, 2017 at 10:10 Comment(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 that break the rule. It's easy to check for this scenario.Benham
<fake-element /> would fail. See Supersharp's answer.Vilberg
@Vilberg - Thanks for pointing out that answer. I've suggested the OP change the accepted mark so I can delete this, get is clearly the better way.Penetrant
B
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;
}
Bye answered 3/3, 2021 at 23:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.