'How to rerender a custom element?
I created a header element which at its initial state shows loading
export const FmHeader = (data) => {
fetch("../../templates/fm-header/index.html")
.then((response) => response.text())
.then((html) => HeaderElement(html));
};
const HeaderElement = (html, data) => {
class FmHeader extends HTMLElement {
constructor() {
super();
var el = this.attachShadow({ mode: "open" });
el.innerHTML = html;
if (data) {
const artistName = el.querySelector(".artist_name");
artistName.innerText = "data.artistName;";
artistName.classList.remove("skeleton");
}
}
}
customElements.define("fm-header", FmHeader);
};
I'm calling it like so:
(function(){
FmHeader();
setTimeout(() => {
FmHeader({data: 'some data from server'});
}, 1000);
})()
I understand the error - that the same element can't be redefined. But is there a way to achieve something like this?
A basic code pen version
Solution 1:[1]
Add content to Web Components with data-attributes, and
<slot>(only in shadowDOM)Attributes are only available in the
connectedCallback, as theconstructorcan run when the Element is not in the DOM (eg.document.createElement("my-artist")Multiple styling options, see: ::slotted CSS selector for nested children in shadowDOM slot
customElements.define("my-artist", class extends HTMLElement {
constructor() {
super()
.attachShadow({mode:"open"})
.innerHTML = `<style>`+
`::slotted([slot="instruments"]) { background: gold }`+
`</style>`+
`<h1 part='artistname'></h1>`+
`<div part='instruments'>Played: <slot name="instruments">No instruments specified</slot></div>`+
`<slot>some facts here</slot>`+
``;
}
connectedCallback(){
this
.shadowRoot
.querySelector("[part='artistname']")
.innerText = this.getAttribute("name");
}
});
*::part(artistname){
/* style shadowDOM parts from global CSS */
font-size:1.2em;
margin:0;
background:blue;
color:gold;
}
body{
font:12px Arial; /* inheritable styles DO style shadowDOM*/
}
<my-artist name="John">John was my favorite!
<span slot="instruments">Many instruments</span>
</my-artist>
<my-artist name="Paul"></my-artist>
<my-artist name="George">
<span slot="instruments">drums</span>
</my-artist>
<my-artist name="Ringo"><span slot="instruments">drums</span></my-artist>
Notes:
note how the slot order is maintained (see John)
George does not show the default
some facts here, because the<my-artist>innerHTML contains spaces (and linebreaks); which get slotted to the default/unnamed<slot>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
