在其构造函数中获取自定义元素的 ID
Getting a custom element's id in its constructor
我正在尝试为网站制作一些可重复使用的 header(多个页面,不能为 copy/paste 一切烦恼);在里面我只有一个 logo-element
元素(也是自定义的),我想让它的 id 等于 header 加上一个 __logo
后缀。
这是javascript:
class TopBar extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
let logoElement = document.createElement("logo-element");
logoElement.setAttribute("id", `${ this.getAttribute("id") }__logo`);
this.shadowRoot.append(logoElement);
}
}
customElements.define('top-bar-element', TopBar);
这里是 HTML:
<top-bar-element id="top-bar"></top-bar-element>
然而,当我检查时,我发现 <logo-element id="null__logo"></logo-element>
。
我想是因为浏览器只在创建元素后才设置属性。
还有其他解释吗?有解决方法吗?
你是对的,在 constructor
阶段元素只在内存中,无法访问 DOM
所以你必须在 connectedCallback
:
customElements.define('my-element', class extends HTMLElement {
constructor() {
let content = ["slot","logo-element"].map(x=>document.createElement(x));
super() // docs are wrong, super doesn't have to be first
.attachShadow({mode: "open" })
.append( ...content );
}
connectedCallback() {
this
.shadowRoot
.querySelector("logo-element")
.id = this.id + "__logo";
console.log(this.shadowRoot.innerHTML);
}
});
<my-element id="ONE">Hello World!</my-element>
没有构造函数
但是你不需要在你自己的元素中构造函数(HTMLElement
中的默认构造函数将被执行)
customElements.define('my-element', class extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: "open"}).innerHTML = `<slot></slot>`;
let el = this.shadowRoot.appendChild(document.createElement("logo-element"));
el.id = this.id + "__logo";
console.log(this.shadowRoot.innerHTML);
}
});
<my-element id="TWO">Hello World!</my-element>
备注:
- 显示设置元素HTML内容的不同用途,您可以混合使用适合您的内容
id
是默认属性(如标题和名称)并且(默认情况下)具有 Getter/Setter
- 您的
logo-element
有效,但仍然是未知元素
- 文档应该说:在
super()
被调用 之前,您不能使用 'this' 范围引用
- shadowDOM 不是必需的;您可以在没有
的情况下创建自定义元素
无阴影DOM
customElements.define('my-element', class extends HTMLElement {
connectedCallback() {
this.innerHTML = `<logo-element id="${this.id}__logo">${this.innerHTML}</logo-element>`;
console.log(this.innerHTML);
}
});
<my-element id="THREE">Hello World!</my-element>
我正在尝试为网站制作一些可重复使用的 header(多个页面,不能为 copy/paste 一切烦恼);在里面我只有一个 logo-element
元素(也是自定义的),我想让它的 id 等于 header 加上一个 __logo
后缀。
这是javascript:
class TopBar extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
let logoElement = document.createElement("logo-element");
logoElement.setAttribute("id", `${ this.getAttribute("id") }__logo`);
this.shadowRoot.append(logoElement);
}
}
customElements.define('top-bar-element', TopBar);
这里是 HTML:
<top-bar-element id="top-bar"></top-bar-element>
然而,当我检查时,我发现 <logo-element id="null__logo"></logo-element>
。
我想是因为浏览器只在创建元素后才设置属性。
还有其他解释吗?有解决方法吗?
你是对的,在 constructor
阶段元素只在内存中,无法访问 DOM
所以你必须在 connectedCallback
:
customElements.define('my-element', class extends HTMLElement {
constructor() {
let content = ["slot","logo-element"].map(x=>document.createElement(x));
super() // docs are wrong, super doesn't have to be first
.attachShadow({mode: "open" })
.append( ...content );
}
connectedCallback() {
this
.shadowRoot
.querySelector("logo-element")
.id = this.id + "__logo";
console.log(this.shadowRoot.innerHTML);
}
});
<my-element id="ONE">Hello World!</my-element>
没有构造函数
但是你不需要在你自己的元素中构造函数(HTMLElement
中的默认构造函数将被执行)
customElements.define('my-element', class extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: "open"}).innerHTML = `<slot></slot>`;
let el = this.shadowRoot.appendChild(document.createElement("logo-element"));
el.id = this.id + "__logo";
console.log(this.shadowRoot.innerHTML);
}
});
<my-element id="TWO">Hello World!</my-element>
备注:
- 显示设置元素HTML内容的不同用途,您可以混合使用适合您的内容
id
是默认属性(如标题和名称)并且(默认情况下)具有 Getter/Setter- 您的
logo-element
有效,但仍然是未知元素 - 文档应该说:在
super()
被调用 之前,您不能使用 'this' 范围引用
- shadowDOM 不是必需的;您可以在没有 的情况下创建自定义元素
无阴影DOM
customElements.define('my-element', class extends HTMLElement {
connectedCallback() {
this.innerHTML = `<logo-element id="${this.id}__logo">${this.innerHTML}</logo-element>`;
console.log(this.innerHTML);
}
});
<my-element id="THREE">Hello World!</my-element>