DEV Community

artydev
artydev

Posted on • Updated on

Create DOM nodes from strings

There are many ways to do it, here is another one :

var htmlstring =  `
  <div>
    <h1>HEllo</h1>
    <button id='btn'>Click Me</button>
  </div>
`;

function mapEvents (node) {
  node.querySelector("#btn").onclick = () => alert("Ciao")
}

function  html(htmlstring) {
  const 
    htmlnode = 0,
    bodynode= 1,
    document = new DOMParser().parseFromString(htmlstring, "text/html"),
    nodes = Array.from(document.childNodes),
    bodyFirstChild = Array.from(nodes[htmlnode].childNodes)[bodynode].firstChild;
    bodyFirstChild.to = function (node) {
      console.log(this)
      node.appendChild(this)
    }
    return bodyFirstChild;
}

function renderPage () {
  let base = html("<div></div>")
  let header = html("<h1>Header</h1>").to(base)
  let title = html("<h1>Content</h1>").to(base)
  let footer = html("<h1>Footer</h1>").to(base)
  document.body.append(base)
}

renderPage()
Enter fullscreen mode Exit fullscreen mode

You can test it here StringToNodes

Another Implementation

let base = null;

var htmlstring =  `
  <div>
    <h1>HEllo</h1>
    <button id='btn'>Click Me</button>
  </div>
`;

function mapEvents (node) {
  node.querySelector("#btn").onclick = () => alert("Ciao")
}

function  html(htmlstring) {
  const 
    htmlnode = 0,
    bodynode= 1,
    document = new DOMParser().parseFromString(htmlstring, "text/html"),
    nodes = Array.from(document.childNodes),
    bodyFirstChild = Array.from(nodes[htmlnode].childNodes)[bodynode].firstChild;
    bodyFirstChild.to = function (node) {
      node.appendChild(this)
      return bodyFirstChild
    }
    return bodyFirstChild;
}

function div () {
  return  html("<div></div>")
}

function header (node=base) {
  let _header = div()
  let title = html("<h1>Header</h1>")
  title.to(_header)
  return _header.to(node)
}

function main (node=base) {
  let _main = div()
  let content = html("<h1>Content</h1>")
  content.to(_main)
  return _main.to(node)
}

function footer (node=base) {
  let _footer = div()
  let foot = html("<h1>Footer</h1>")
  foot.to(_footer)
  return _footer.to(node)
}

function stick(node) {
  base = node
}

function renderPage () {
  let base = div()
  stick(base)
  header()
  main()
  footer()
  document.body.append(base)
}

renderPage()


Enter fullscreen mode Exit fullscreen mode

You can test it here StringToNode

Another variation


const parser = new DOMParser();

function html(template) {
  const toNode = (s) => parser.parseFromString(s, "text/html").body.firstChild;
  var text = typeof template == 'string' ? [template] : [template[0]];
  for (var i = 1, length = arguments.length; i < length; i++) {
    text.push(arguments[i], template[i]);
  }
  let node = toNode(text.join(''))
  node.to = function (base) {
    base.append(this)
    return node
  }
  return node
}


function Header (base) {
  return  html`<h1>HEader</h1>`.to(base)
}

function Main (base) {
    return  html`<h1>Main</h1>`.to(base)
}

function Footer(base) {
  return  html`<h1>Footer</h1>`.to(base)
}

function App () {
  const 
    base = html`<div />`,
    baseHeader = html`<div />`.to(base),
    baseFooter = html`<div />`.to(base),
    baseMain = html`<div />`.to(base);
  Header(baseHeader)
  Main(baseMain)
  Footer(baseFooter)
  return base
}

document.body.append(App())

Enter fullscreen mode Exit fullscreen mode

Top comments (0)