Skip to content

Virtual DOM ​

virtualDom.html ​

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Virtual DOM</title>
  </head>

  <body>
    <div id="root"></div>
    <script>
      /**
       * Create Element
       *
       * @param {string} tagName HTML Tag Name
       * @param {*} props Attributes & Children
       * @returns {*} Element
       */
      const createElement = (tagName, { attrs = {}, children = [] } = {}) => ({
        tagName,
        attrs,
        children
      });

      /**
       * Render
       *
       * @param {*} element TagName, Attributes & Children
       * @returns {HTMLElement} HTML Element
       */
      function render({ tagName, attrs = {}, children = [] }) {
        const element = document.createElement(tagName);

        // Append all children into the parent element
        children.forEach(child => {
          if (typeof child === "string") {
            // If the child is a string, create a new text node object
            element.appendChild(document.createTextNode(child));
          } else {
            // Else (re)call the render function, with the children elements
            element.appendChild(render(child));
          }
        });

        const attrsEntries = Object.entries(attrs);

        // If there are attributes, it adds them to the parent element
        if (attrsEntries.length) {
          for (const [key, value] of attrsEntries) {
            element.setAttribute(key, value);
          }
        }

        return element;
      }

      /**
       * Mount
       *
       * @param {HTMLElement} element
       * @param {HTMLElement} rootElement
       */
      function mount(element, rootElement) {
        rootElement.replaceWith(element);
      }

      /* Components */
      const titleElement = createElement("h1", {
        attrs: { id: "title" },
        children: ["Hello World"]
      });

      const loremIpsumElement = createElement("p", {
        attrs: { class: "lorem-ipsum" },
        children: ["Lorem ipsum dolor sit amet"]
      });

      const divElement = createElement("div", {
        children: [titleElement, loremIpsumElement]
      });

      const element = render(divElement);
      mount(element, document.getElementById("root"));
    </script>
  </body>
</html>

Released under the MIT License.