Reputation: 6654
Consider a simple web component
class TimeAgo extends HTMLElement {
constructor() {
super();
this.innerHTML = '2 hours ago'
}
}
customElements.define('time-ago', TimeAgo);
Being used like this
This post was created <time-ago datetime="2020-09-26T11:28:41.9731640+01:00">September 26th</time-ago>
When the page renders, the browser will first write "September 26th" and right after that switch to "2 hours ago".
Is there a way to prevent this from happening? I'd much prefer to display "2 hours" on first paint.
The JS file is loaded through a CDN, moving the script tag up and down the response didn't change anything.
Upvotes: 6
Views: 2019
Reputation: 21193
But is your element defined and its script executed before that part of the DOM is parsed?
Code below displays 1A because the 1 is injected into the DOM before content A is parsed.
So if you don't want a FOUC leave <time-ago>
content empty.. or maybe blur it with CSS
<script>
window.onload = () => console.log("onload");
customElements.define( "my-element", class extends HTMLElement {
constructor() {
super();
console.log("constructor");
}
connectedCallback() {
console.log("connectedCallback");
this.innerHTML = "1";
}
}
);
</script>
<my-element>A</my-element>
<script>
console.log("end DOM");
</script>
Upvotes: 4
Reputation: 12884
One of the possible solution I can think of is to enable shadow-dom
class TimeAgo extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.innerHTML = '2 hours ago'
}
}
customElements.define('time-ago', TimeAgo);
By defining your web component to be shadow dom, you can change the content even before it's attached to the DOM.
Upvotes: 1