Web 组件 - 不接受任何子元素
web component - accept no child elements
如何定义一个像 <img>
一样工作的 Web 组件,因为它不接受任何子元素?
<script>
const QA = (q, d) => Array.prototype.slice.call((d||document).querySelectorAll(q), 0);
const QS = (q, d) => (d||document).querySelector(q);
</script>
<template id="push-message">
<style>
message { display: grid; font-family: sans-serif; background: #eee; outline: 1px solid; }
.badge { }
</style>
<message>
<img class="badge">
<img class="icon">
<img class="image">
</message>
</template>
<script>
const wpm = 'push-message';
customElements.define(wpm,
class extends HTMLElement {
constructor() {
super();
const l = QS(`#${wpm}`).content.cloneNode(true);
const s = this.attachShadow({ mode: 'open' }); s.appendChild(l);
}
QS(q) { return QS(q, this.shadowRoot); }
QA(q) { return QA(q, this.shadowRoot); }
static get observedAttributes() { return [ "badge", "icon", "image" ]; }
attributeChangedCallback(a, o, n) {
if (/^(badge|icon|image)$/.test(a))
this.QS(`.${a}`).src = n;
}
});
</script>
<push-message
badge="//google.com/favicon.ico"
icon="//google.com/favicon.ico"
image="//google.com/favicon.ico">
<p>ok</p>
DOM
应该是
<push-message></push-message>
<p></p>
没有
<push-message><p></p></push-message>
和ok
应该显示在结果中。
有没有办法更改 customElements.define
以避免必须显式关闭 <push-message></push-message>
并仅使用 <push-message>
但隐式自关闭?
Self-closing 标签称为 void elements.
据我所知,无法创建自定义空元素。总而言之,它需要更改浏览器 HTML 解析器,这对于网络社区来说并不是一件容易的事。由于浏览器实现 tag-soup algorithm.
的方式,需要进行更改
因此您需要一个结束标记。您可以在此处阅读更多相关信息:
附带说明一下,如果您有自己的模板 compiler/parser,例如 vue-compiler
和 ng-compiler
,您可以指示它理解 self-closing 自定义元素构建时间。然而,实现这一点的好处实际上是 non-existent.
自治自定义元素需要结束标记:Do custom elements require a close tag?
您可以创建从 HTMLImageElement 扩展的自定义 Built-In 元素
获得一个 self-closing IMG 标签:
<img is="push-message" badge="//google.com/favicon.ico">
<img is="push-message" icon="//google.com/favicon.ico">
<img is="push-message" image="//google.com/favicon.ico">
<p>ok</p>
但是一个IMG只能有一个src,所以你不妨创建3个元素并使用
<img is="message-badge">
<img is="message-icon">
<img is="message-image">
如何定义一个像 <img>
一样工作的 Web 组件,因为它不接受任何子元素?
<script>
const QA = (q, d) => Array.prototype.slice.call((d||document).querySelectorAll(q), 0);
const QS = (q, d) => (d||document).querySelector(q);
</script>
<template id="push-message">
<style>
message { display: grid; font-family: sans-serif; background: #eee; outline: 1px solid; }
.badge { }
</style>
<message>
<img class="badge">
<img class="icon">
<img class="image">
</message>
</template>
<script>
const wpm = 'push-message';
customElements.define(wpm,
class extends HTMLElement {
constructor() {
super();
const l = QS(`#${wpm}`).content.cloneNode(true);
const s = this.attachShadow({ mode: 'open' }); s.appendChild(l);
}
QS(q) { return QS(q, this.shadowRoot); }
QA(q) { return QA(q, this.shadowRoot); }
static get observedAttributes() { return [ "badge", "icon", "image" ]; }
attributeChangedCallback(a, o, n) {
if (/^(badge|icon|image)$/.test(a))
this.QS(`.${a}`).src = n;
}
});
</script>
<push-message
badge="//google.com/favicon.ico"
icon="//google.com/favicon.ico"
image="//google.com/favicon.ico">
<p>ok</p>
DOM
应该是
<push-message></push-message>
<p></p>
没有
<push-message><p></p></push-message>
和ok
应该显示在结果中。
有没有办法更改 customElements.define
以避免必须显式关闭 <push-message></push-message>
并仅使用 <push-message>
但隐式自关闭?
Self-closing 标签称为 void elements.
据我所知,无法创建自定义空元素。总而言之,它需要更改浏览器 HTML 解析器,这对于网络社区来说并不是一件容易的事。由于浏览器实现 tag-soup algorithm.
的方式,需要进行更改因此您需要一个结束标记。您可以在此处阅读更多相关信息:
附带说明一下,如果您有自己的模板 compiler/parser,例如 vue-compiler
和 ng-compiler
,您可以指示它理解 self-closing 自定义元素构建时间。然而,实现这一点的好处实际上是 non-existent.
自治自定义元素需要结束标记:Do custom elements require a close tag?
您可以创建从 HTMLImageElement 扩展的自定义 Built-In 元素
获得一个 self-closing IMG 标签:
<img is="push-message" badge="//google.com/favicon.ico">
<img is="push-message" icon="//google.com/favicon.ico">
<img is="push-message" image="//google.com/favicon.ico">
<p>ok</p>
但是一个IMG只能有一个src,所以你不妨创建3个元素并使用
<img is="message-badge">
<img is="message-icon">
<img is="message-image">