using custom elements的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' });

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

最佳答案

由于以下原因,您无法做到这一点:

customElements.define('word-count2', WordCount2, {extends: 'p'});
用于扩展built-in elements
您必须走Autonomous custom element路线as per the docs
这是一个主意:

// 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>

09-25 18:30
查看更多