Replacing Content
One special thing about Markup template is that it is an instance object, which you can do a lot of things to. One of these things is the ability to replace one template with the another.
Let's take for example an async rendering scenario where you render a loading indicator then need to replace this loading indicator with the actual loaded content.
const loadingIndicator = html`<p>loading...</p>`;
const fetchContent = () => {
setTimeout(() => { // simulate HTTP call
const content = html`<p>loaded content</p>`;
// render content by telling it what to replace
content.replace(loadingIndicator)
}, 2500)
}
html`${loadingIndicator}`
.render(document.body);
fetchContent();
The above example will initially render the
loading...
text and after 2.5 seconds it will
replace it with the content template.
The replace method will insert the not-yet-rendered template nodes in the place in the DOM the target template was rendered. This means that you can have multiple tags, and it will just replace them all.
Replacing HTML Element
You may also target a specific DOM Element. Here is the same example but with the loading indicator as an Element instead of an HTML Template.
// using a HTMLParagraphElement instance
const loadingIndicator = document.createElement('p');
loadingIndicator.textContent = 'Loading...'
const fetchContent = () => {
setTimeout(() => {
const content = html`<p>loaded content</p>`;
content.replace(loadingIndicator)
}, 2500)
}
html`${loadingIndicator}`
.render(document.body);
fetchContent();
Replacing "Must known"
- The target template must be already rendered in the DOM in order for the "replacing" to happen.
-
The target can be an
Element
instance but it cannot be
HTMLBodyElement
,HTMLHeadElement
,HTMLHtmlElement
, orShadowRoot
as these are crucial elements in the document. - If the replacement template has not been yet rendered, it will but if it is already rendered somewhere else in the DOM, it will be moved from that location to the location where the target is.