DEV Community

Cover image for Fighting the <div> soup with a 5 minute instant Web Component
Danny Engelman
Danny Engelman

Posted on • Edited on

Fighting the <div> soup with a 5 minute instant Web Component

I was inspired to write this blog by this React based textGenerate effect

It is a huge site, the JavaScript is close to 1 MB:

creating my <text-reveal> Web Component

The banner above was created by DALL-E (Chat-GPT)

create a Dali like wide banner with a stopwatch folded over a Web Component JavaScript code in a soup filled with HTML <div> tags

I then fired up the Web Component Generator I created in the GPT-Store last month, and gave it the prompt:

(Open the link above with Ctrl+Click, OpenAI sometimes blocks access)

Create a Web Component where words fade in one by one for the sentence:
"Oxygen gets you high. In a catastrophic emergency, we're taking giant, panicked breaths. Suddenly you become euphoric, docile. You accept your fate. It's all right here. Emergency water landing, six hundred miles an hour. Blank faces, calm as Hindu cows"

It spit out this code:

<script>
customElements.define('reveal-words', class extends HTMLElement {
  constructor() {
    const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);
    super();
    this.attachShadow({ mode: 'open' });
    this.shadowRoot.append(createElement('style', {
      innerHTML: `
        :host { display: block }
        span {
          opacity: 0;
          display: inline-block;
          animation: fade-in 1s ease-out forwards;
        }
        @keyframes fade-in { to { opacity: 1 }
        }`
    }), this.createElement('div'));
  }

  connectedCallback() {
    const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);    
    setTimeout(() => {
      this.words = this.innerText.trim().split(/\s+/);
      this.div = this.shadowRoot.querySelector('div';
      this.div.append(...this.words.map((word, index) => createElement('span', {
        innerHTML: word + ' ',
        style: `animation-delay: ${index * 100}ms`
      })));
    });
  }
});
</script>

<reveal-words>Oxygen gets you high. In a catastrophic emergency, we're taking giant, panicked breaths. Suddenly you become euphoric, docile. You accept your fate. It's all right here. Emergency water landing, six hundred miles an hour. Blank faces, calm as Hindu cows</reveal-words>
Enter fullscreen mode Exit fullscreen mode

I can do better,

The <reveal-words> Web Component

So I pasted it in JSFiddle, and refactored it by hand
Moving all code to the connectedCallback

Done in 5 minutes (click the result tab)




Top comments (0)