首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >未能构建CustomElement

未能构建CustomElement
EN

Stack Overflow用户
提问于 2022-04-01 14:23:22
回答 3查看 282关注 0票数 1

我遇到了使用自定义元素的问题。

错误: Uncaught DOMException: Failed to construct 'CustomElement': The result must not have children

代码语言:javascript
运行
复制
'use strict';

class TestCard extends HTMLDivElement {

  constructor() {
    super();
    this.headerNode = document.createElement('div');
    this.bodyNode = document.createElement('div');
    this.headerNode.className = 'card__header';
    this.bodyNode.className = 'card__body';
    this.appendChild(this.headerNode);
    this.appendChild(this.bodyNode);
  }

  connectedCallback() {
    this.classList.add('card');
  }

  static get observedAttributes() {
    return ['data-header', 'data-body'];
  }

  attributeChangedCallback(attrName, oldValue, newValue) {
    if (newValue !== oldValue) {
      this[attrName.replace('data-', '')] = newValue;
    }
  }

  set header(value) {
    this.headerNode.textContent = value;
    this.setAttribute('data-header', value);
  }

  set body(value) {
    this.bodyNode.innerHTML = value;
    this.setAttribute('data-body', value);
  }
}

customElements.define('test-card', TestCard, {
  extends: 'div'
});
代码语言:javascript
运行
复制
<div is="test-card" data-header="Title" data-body="Content"></div>

创建WebComponent :

代码语言:javascript
运行
复制
var cardNode = document.createElement('div');
cardNode.setAttribute('is', 'test-card');
cardNode.header = header;
cardNode.body = body;
EN

Stack Overflow用户

回答已采纳

发布于 2022-04-01 15:09:31

在自定义元素的构造函数中,有些东西是不允许的。有关此选项的更多信息,请查看我对一个类似问题的老回答)。

除其他外,其中包括:

  • 访问属性(特别是写入属性,这包括class,它被认为是由使用组件的人控制的)
  • 访问子 (既不读也不写)
    • ,除非在组件的阴影树中这样做。

要实现您想要做的事情,请使用阴影DOM:

代码语言:javascript
运行
复制
class TestComp extends HTMLElement {
  headerNode = document.createElement('div');
  bodyNode = document.createElement('div');
  
  constructor() {
    super();
    this.attachShadow({mode: 'open'});
    this.headerNode.className = 'card__header';
    this.bodyNode.className = 'card__body';
    this.bodyNode.part = 'body';
    this.shadowRoot.append(this.headerNode, this.bodyNode);
  }
  
  connectedCallback() {
    this.classList.add('card');
  }

  static get observedAttributes() {
    return ['data-header', 'data-body'];
  }

  attributeChangedCallback(attrName, oldValue, newValue) {
    if (newValue !== oldValue) {
      this[attrName.replace('data-', '')] = newValue;
    }
  }

  set header(value) {
    this.headerNode.textContent = value;
    this.dataset.header = value;
  }

  set body(value) {
    this.bodyNode.innerHTML = value;
    this.dataset.body = value;
  }
}

customElements.define('test-comp', TestComp);

let newTestComp = new TestComp();
newTestComp.header = 'FOOO';
newTestComp.body = '<ul><li><i>BA</i><b>AA</b>R</ul>';
document.body.append(newTestComp);
代码语言:javascript
运行
复制
test-comp::part(body) { color: green; }
代码语言:javascript
运行
复制
<test-comp data-header="Titre de ma carte" data-body="<h1>Test</h1>"></test-comp>

请注意,使用影子DOM意味着外部样式不会影响阴影树中元素的样式。要将样式应用于这些样式,请在构造函数中创建一个<style>元素,将它的textContent属性设置为您的样式,并将其附加到阴影DOM中其他元素的旁边。

与使用style元素不同,您还可以使用可构造样式表。您可能需要一个聚脂填充,因为到目前为止,基于铬的浏览器是唯一支持它的浏览器,但在其他浏览器中正在提供支持。已经有一段时间了:打开新选项卡,导航到about:config,然后将layout.css.constructable-stylesheets.enabled设置为true)。

要允许从外部CSS对组件内部进行样式化,可以使用阴影DOM中的part="name"属性从外部样式化哪些元素,然后使用CSS中的::part(name)选择器对其进行样式设置。将其添加到代码示例中。

票数 3
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71708470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档