Create DOM nodes from strings
Tags: html, javascript
Published: 2023-03-15 12:46:25

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

```js
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()
```
You can test it here [StringToNodes](https://flems.io/#0=N4IgtglgJlA2CmIBcA2A7AOgKxYDQgDMIEBnZAbVADsBDMRJEDACwBcxYR8BjAeytbwByECAC+uanQZMAVmR79BwxgDcaAJwAEbDiVYaIVAOZaAvFq0ADADpVLAHigRVAPjuXHzAIyuAEgCisLC8DgD0Pu72ng4ARgCurKz8WtBmAOSxrFTprgDCsBDcANZaALLw4QlJ-FGOYc5udlYA3HZ2BPFU3KwQKWA0AA4BqkKsJFoAFFS8UPAAlFrAHlozcxgAjvHwGgCeAMrwCD28GpM2IADEWVQX8xj83IUl5lOLZq5aNAgarOcgeQgNF4dzsYnaVE63V6KR07Fgk10sH0hhMi2W0T4VH0WhWliRa3grwADLg8VpYrNdoSLN4ydFLFBeNx4vQBK8qPAAO5aAAiAHkygAFTQkHaTe6DUXwABiGl4YH2BiMxkR8JRKtwuJAggAHqwIvC7vTPKtZvAJhYAIIaDQ0XYYAjysCTJkstmsDDcZjEKAAOXNJHmJs8lKguxlEA0+jyPtgUFeNrtDqdCumgfIBPNAF0vXH-YH5uQw9Sc46ozH820GRSqZHo6xY76MMlXlCen17Om5ujyZYsSReAgMCFVawfUG+2b1kNBkIoE345NxxBJzXwTWNPBWPENPYS-XK77qxuOl0Oykt1Q5hoRcYiRKlisEKwKTQxa8kf8nC5XOFGu4IDzM+246PANA3p+8LfpEfjgTe4SRHcLa8JMsTvgsIGvr0rAIFBHAwb4eRKGMiG+MhyRoRhwHRC+WgELwvCCNoFhfhcDiRDKjHMWRgH3JR6FijRjLMqyYwYCWGCzvOVFCWCEJXjed7wBKEIQvAuqDKcr7AGIXAgGKxwwtiIgAJxIN44iSCAtD0CIXokAoIBYsorAiOI2ZiEAA)

Another Implementation 

```js
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()


```

You can test it here [StringToNode](https://flems.io/#0=N4IgtglgJlA2CmIBcB2AjAOgCwCYA0IAZhAgM7IDaoAdgIZiJIgYAWALmLCAQMYD21NvEHIQIAL54a9RswBW5XgKEimCNgAIARrVLwNAXg3UArrFgBuADrUbAN1oAnDe06k2jiNQDmhjRoADG38AHigIOwA+YP8NEJY0SIAJAFFzPhCAegTo6li4rRM2NgENaAMAci02agrIgGFYCB4Aaw0AWXgswuKBXNDM8KibAOtbakITah42CFKwWgAHFLthNlINAApqPih4AEoNYBidvYwARxN4RwBPAGV4BBm+R02rEABiatsQfYwBHhNVp+TaHAyRDS0BCONhvED1CC0PjvfY2cQ2GyTaazUouDiwTauWDuTw+Q7HPIafjUdwaGL+ImnfRGAAMeHp2l2NyZRjQ7Mp-igfB4JgYgj81HgAHcNAARADy7QACk49K8-otVfAAGKOPhgO4eLzeQn4knGvB0kBCAAebGy+JR-PyTI2RgAgo5HLQbhhCHqwJshSKxWwMDwWCQoAA5XbwUj7Z2xLRc7UQRzueqR2BQPye72+-367Zx0gURlxgC64ezMdL+woKag3KrfvTmdrY3yTZuaYzbCzUYwJT8WJmczyJb25I5-iZGCWi2EUEHOc2bEjCdnGkc8DYJkceR7fY7UY56IFO73B6PqfbA87aIxEym49KQy2M8pu-3h4Z+LhMIIkiLIhmiX4n3GMccTyFh4FoPZnCneADB0PQv38dQNAAfTghDrj8IZQRiLDZjYBA-CJQCciSeDEKyHIURiMiEGHPhNlwujrlRb9rz-Tj8McNjkJ4i9MVfGCNAWLwth5NCDiOEi9xw6S8iMIieMw5TqRUTQjCo954kSeplDWBjEiYykdLWYTsNUzSr1-PI7NoLxhKZUTn2gicNEIPg+CEJC5N0BSKS0zRsL8gKCPUiJiMpLCor0vFOGoxJtX8wLzPAhyktspLuJiH8bxwgqhJKETIPE7EfPcZoWhExTKXkiU4yql8atKXdqEQlVvH0UEmvC7QQsIuKHLq1pNnkhy8MQ+L-FUhbfMy65luDUUbJ7BdFiXHrppCzzxm63raH6+LnxseAbUWF5NGAcRuBAPQnhg8gmAANhQJAWQAWhZH6JCkEA6AYURw1IRQQGs1QQB7IapKcbwZKQDQWS7DRNRgY0NFR9GYhTG1ftICAAC9jVRlNHEQ37CbGMTqAAKgRhZHGR6gfoxrHwh8Tn2tYLjnDCjQpWgDdUbQFkWQAUgxuCIG8dhUYAVhZRYbQx-hYBeVGpUjIQMaaSVfvlxW2CQVX1YxnRWm8PUpigVGPilrBla++nnwwVSEdNpWNFVtWNf5sqEZtlo7b4B2nZdt2UE1vhtccXX9fgOX4AVv3JcDrm+BJmCkFoLRSATopU4JgKSjAPnKVFqBxaz6W0Sel74DfGlRDQD6kBwHAJErcQgA)

Another variation 

```js
 
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())

```