构建失败'CustomElement':结果不能有父级

Failed to construct 'CustomElement': The result must not have a parent

我正在使用 Web Components

创建自定义 HTML 元素

我通过 REST 服务检索了一些 JSON 数据,并希望根据响应动态创建自定义元素。

class LibraryFolders extends HTMLElement {
    async connectedCallback() {
        // Load folders
        const foldersResponse = await fetch('/wp-json/prodes-media-library/v1/folders');
        const foldersResponseJson = await foldersResponse.json();

        foldersResponseJson.forEach(folder => {
            document.createElement('library-folder');
        });
    }
}

customElements.define('library-folders', LibraryFolders);

这工作正常,当使用 createElement 创建元素时,它调用 customElement class 中的 constructor 调用 LibraryFolder

class LibraryFolder extends HTMLElement {
    constructor() {
        super();

        // logs <library-folder></library-folder>
        console.log(this);

        // This results eventually into the following error:
        // Failed to construct 'CustomElement': The result must not have a parent
        document.querySelector('#folders').appendChild(this);
    }
}

customElements.define('library-folder', LibraryFolder);

我尝试实现的是 library-folder 元素 library-folder 元素添加到名为 <div id="folders"></div> 的元素中,一旦 constructor 中的 [=] 19=] 被解雇了。

但是,尝试这样做会导致以下错误:

Uncaught DOMException: Failed to construct 'CustomElement': The result must not have a parent
    at HTMLDocument.createElement (:1:1536)
    at HTMLDocument.document.createElement (:292:44)
    at (URL)
    at Array.forEach ()
    at HTMLElement.connectedCallback (URL)

我在这里做错了什么?与其他类似错误不同,文档中没有关于此错误的信息。

感谢@pointy让我走上了正确的方向。

An element that adds itself to the DOM would be weird. (For one thing, it wouldn't work independently of a particular page structure.)


问题是我试图将 元素 使用它自己的 constructor 添加到 DOM,我还发现,如果你设法让它在 constructor 内工作,它将导致。

Maximum call stack size exceeded.

我设法通过在 class 中创建一个函数来解决这个问题,稍后可以调用该函数将 元素 附加到 DOM.

class LibraryFolder extends HTMLElement {
    constructor() {
        super();
    }

    appendToDom() {
        // Moved this outside the constructor
        document.querySelector('#folders').appendChild(this);;
    }
}

customElements.define('library-folder', LibraryFolder);

然后在 LibraryFolders class 中调用该函数。

class LibraryFolders extends HTMLElement {
    async connectedCallback() {
        // Load folders
        const foldersResponse = await fetch('/wp-json/prodes-media-library/v1/folders');
        const foldersResponseJson = await foldersResponse.json();

        foldersResponseJson.forEach(folder => {
            const node = document.createElement('library-folder');

            // Now it works correctly :)
            node.appendToDom();
        });
    }
}

customElements.define('library-folders', LibraryFolders);

补充一下,根据规范,这个错误是正确的。 If result’s parent is not null, then throw a "NotSupportedError" DOMException.

Chrome 没有给出正确的错误,但如果你在 Firefox 中尝试,你会得到指定的错误

有关更多详细信息,请查看 https://dom.spec.whatwg.org/#dom-document-createelement