3

使用自定义元素的 MDN 文档中,他们详细介绍了自定义内置元素的示例:

customElements.define('expanding-list', ExpandingList, { extends: "ul" });

允许这种用法:

<ul is="expanding-list">

  ...

</ul>

我想知道是否可以以相同的方式自定义另一个自定义元素?例如,如果我创建了一个名为 的元素custom-element,并且我想要它的变体,我可能想要创建一个新special-custom-element类,并以相同的方式定义它,以便能够像这样使用它:

<custom-element is="special-custom-element">

  ...

</custom-element>

但是,我收到一条错误提示: Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': "custom-element" is a valid custom element name

尝试运行以下命令时:

customElements.define('special-custom-element', SpecialCustomElement, { extends: 'custom-element' });

这是我做错了什么,还是这种行为严格限于内置元素?除了我链接到的页面上的内容之外,我发现很难找到有关此行为的任何信息,因此我希望从更了解规格的人那里获得一些建议。

4

2 回答 2

1

你不能按照你想要的方式去做,因为:

您可以创建两种类型的自定义元素:

自治自定义元素:独立元素;它们不继承自内置 HTML 元素。

定制的内置元素:这些元素继承自并扩展了内置 HTML 元素。

customElements.define('word-count2', WordCount2, {extends: 'p'});

用于扩展built-in elements.

您必须按照文档Autonomous custom element路线

这是一个想法:

// Create a class for the element
class MyElement extends HTMLElement {
  constructor(text) {
    // Always call super first in constructor
    super();
    // Create a shadow root
    var shadow = this.attachShadow({
      mode: 'open'
    });
    // Create the span
    var wrapper = document.createElement('span');
    wrapper.textContent = !!text ? text : 'foo';

    shadow.appendChild(wrapper);
  }
}

class MyElement2 extends MyElement {
  constructor() {
    // Always call super first in constructor
    super('bar');
  }
}

// Define the new element
customElements.define('my-element', MyElement);
customElements.define('my-element2', MyElement2);
<div>
  <my-element text="">
</div>
<div>
  <my-element2 text="">
</div>

现在你仍然可以扩展你的类(并定制一个内置元素)并访问它的输出,super这可能对你有用,并且在某种程度上可能会让你得到你需要的东西:

// Create a class for the element
class WordCount extends HTMLParagraphElement {
  constructor() {
    // Always call super first in constructor
    super();

    // count words in element's parent element
    const wcParent = this.parentNode;

    function countWords(node) {
      const text = node.innerText || node.textContent;
      return text.split(/\s+/g).length;
    }

    const count = `Words: ${countWords(wcParent)}`;

    // Create a shadow root
    const shadow = this.attachShadow({
      mode: 'open'
    });

    // Create text node and add word count to it
    const text = document.createElement('span');
    text.textContent = count;

    // Append it to the shadow root
    shadow.appendChild(text);

    // Update count when element content changes
    text.textContent = count;
  }
}

class WordCount2 extends WordCount {
  constructor() {
    // Always call super first in constructor
    super();
    console.log(this.shadowRoot.textContent)
  }
}

// Define the new element
customElements.define('word-count', WordCount, {
  extends: 'p'
});
customElements.define('word-count2', WordCount2, {
  extends: 'p'
});
<div>
  <h2>Sample heading</h2>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pulvinar sed justo sed viverra. Aliquam ac scelerisque tellus. Vivamus porttitor nunc vel nibh rutrum hendrerit. Donec viverra vestibulum pretium. Mauris at eros vitae ante pellentesque bibendum.
    Etiam et blandit purus, nec aliquam libero. Etiam leo felis, pulvinar et diam id, sagittis pulvinar diam. Nunc pellentesque rutrum sapien, sed faucibus urna sodales in. Sed tortor nisl, egestas nec egestas luctus, faucibus vitae purus. Ut elit nunc,
    pretium eget fermentum id, accumsan et velit. Sed mattis velit diam, a elementum nunc facilisis sit amet.</p>
  <p is="word-count"></p>
</div>

<div>
  <h3>Sample heading</h3>
  <p>Lorem ipsum dolor sit amet, consec Sed tortor nisl, egestas nec egestas luctus, faucibus vitae purus. Ut elit nunc, pretium eget fermentum id, accumsan et velit. Sed mattis velit diam, a elementum nunc facilisis sit amet.</p>
  <p is="word-count2"></p>
</div>

于 2018-08-01T16:52:18.063 回答
0

你也可以做这个类 SpecialCustomElement extends CustomElement { ... } customElements.define('special-custom-element', SpecialCustomElement, { extends: 'ul' });

并可以将其用作

...
于 2019-07-29T21:32:58.613 回答