Tag: serialize

  • HTMLElement to Virtual DOM and back

    /**
     * @param {HTMLElement} 
     * @return {object} object literal presentation
     */
    function virtualize(element) {
      if (element.nodeType === 3)
        return element.textContent;
      const ret = {
        type: element.tagName.toLowerCase(),
        props: {
          children: []
        }
      };
      element.childNodes.forEach(child => ret.props.children.push(virtualize(child)));
      if (ret.props.children.length === 1)
        ret.props.children = ret.props.children[0];
      for (const {
          name,
          value
        } of element.attributes)
        ret.props[name === 'class' ? 'className' : name] = value;
      return ret;
    }
    
    /**
     * @param {object} valid object literal presentation
     * @return {HTMLElement} 
     */
    function render(obj) {
      if (typeof obj === 'string') return document.createTextNode(obj);
      const {
        type,
        props: {
          children,
          ...attributes
        }
      } = obj;
      const ret = document.createElement(type);
      const childNodes = typeof children === 'string' ? [children] : children;
      childNodes.forEach(childNode => ret.append(render(childNode)));
      for (const [key, val] of Object.entries(attributes)) {
        ret.setAttribute(key === 'className' ? 'class' : key, val)
      }
      return ret;
    }

    Demo