检测 dom 元素是自定义 Web 组件还是 html 元素

Detect if dom element is custom web component or html element

在给定的 html 中,我如何判断 dom 元素是浏览器定义的标准 html 组件还是脚本中定义的 Web 组件(由作者):

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

我知道无法以编程方式检查 Web 组件是否已注册。他们也被认为是 HTMLElement。有没有办法检查 dom 节点是标准 html 还是自定义 Web 组件?假设我使用 querySelector()

获得 dom 元素

custom element 的名称 需要 包含 -,而 HTML 定义的元素则不需要。所以:

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

(或者 .indexOf("-") != -1 对于还没有 String#includes 的旧浏览器。)

要检测 DOM 元素是否为已注册的自定义元素,您应该使用 customElements.get()

如果该元素尚未注册或者它是标准 HTML 元素,该方法将 return undefined.

如果它是已注册的自定义元素,它将 return 其 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>

您应该考虑到有些自定义标签名称可能未定义为自定义元素。例如document.createElement('custom-tagname').

如果您想检查它是否真的是已注册自定义元素的实例,您可以使用 instanceof:

function isDefinedCustomElement(node) {
    if (node.tagName.includes("-")) {
        return false;
    }
    const customElementClass = window.customElements.get(node.tagName.toLowerCase());
    return customElementClass && node instanceof customElementClass;
}