你可以 'customize' 非内置元素吗?
Can you 'customize' non built-in elements?
在 using custom elements 的 MDN 文档中,他们详细介绍了自定义内置元素的示例:
customElements.define('expanding-list', ExpandingList, { extends: "ul" });
允许这种用法:
<ul is="expanding-list">
...
</ul>
我想知道是否可以用同样的方式自定义另一个自定义元素?例如,如果我创建了一个名为 custom-element
的元素,并且我想要它的变体,我可能想要创建一个新的 special-custom-element
class,并以相同的方式定义它,以便能够像这样使用它:
<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' });
这是我做错了什么,还是这种行为仅限于内置元素?我发现很难找到关于此行为的任何信息,除了我链接到的页面上的信息,所以我希望能从更了解规范的人那里得到一些建议。
你不能按照你想要的方式去做,因为:
There are two types of custom elements you can create:
Autonomous custom element: Standalone elements; they don't inherit from built-in HTML elements.
Customized built-in element: These elements inherit from — and extend — built-in HTML elements.
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>
现在您仍然可以扩展 class( 并自定义内置元素)并访问 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>
你也可以这样做
class SpecialCustomElement 扩展了 CustomElement
{
...
}
customElements.define('special-custom-element', SpecialCustomElement, { extends: 'ul' });
并且可以用作
...
在 using custom elements 的 MDN 文档中,他们详细介绍了自定义内置元素的示例:
customElements.define('expanding-list', ExpandingList, { extends: "ul" });
允许这种用法:
<ul is="expanding-list">
...
</ul>
我想知道是否可以用同样的方式自定义另一个自定义元素?例如,如果我创建了一个名为 custom-element
的元素,并且我想要它的变体,我可能想要创建一个新的 special-custom-element
class,并以相同的方式定义它,以便能够像这样使用它:
<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' });
这是我做错了什么,还是这种行为仅限于内置元素?我发现很难找到关于此行为的任何信息,除了我链接到的页面上的信息,所以我希望能从更了解规范的人那里得到一些建议。
你不能按照你想要的方式去做,因为:
There are two types of custom elements you can create:
Autonomous custom element: Standalone elements; they don't inherit from built-in HTML elements.
Customized built-in element: These elements inherit from — and extend — built-in HTML elements.
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>
现在您仍然可以扩展 class( 并自定义内置元素)并访问 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>
你也可以这样做 class SpecialCustomElement 扩展了 CustomElement { ... } customElements.define('special-custom-element', SpecialCustomElement, { extends: 'ul' });
并且可以用作
...