2021-10-07 DOM Renderer

domRenderer

by Ttt Yyy

JavaScript

class DOMRenderer {
  generateNode(node) {
    if (typeof node === "string") {
      return document.createTextNode(node);
    }
    const { props, type } = node;

    /* START FOLLOW UP DON'T DO ON INITIAL IMPLEMENTATION*/
    if (typeof type === "function") {
      return this.generateNode(type(props));
    }
    /* END FOLLOW UP*/
    const element = document.createElement(type);
    // assuming props is object
    for (let key in props) {
      const value = props[key];
      if (key === "children") {
        if (Array.isArray(value)) {
          // create fragment to append children once instead of adding each child to DOM; this prevents thrashing of relayout/reflow
          const fragment = document.createDocumentFragment();
          for (let child of value) {
            fragment.appendChild(this.generateNode(child));
          }
          element.appendChild(fragment);
        } else {
          element.appendChild(this.generateNode(value));
        }
      } else {
        element.setAttribute(key, value);
      }
    }

    return element;
  }
  render(node, container) {
    container.appendChild(this.generateNode(node));
    console.log(container);
  }
}
const app = {
  type: "div",
  props: {
    id: "app",
    children: [
      {
        type: "h1",
        props: {
          class: "header",
          children: "Hello, World!",
        },
      },
      {
        type: "h1",
        props: {
          class: "header",
          children: "Hello, World 2!",
        },
      },
    ],
  },
};

const renderer = new DOMRenderer();
renderer.render(app, document.body);