Get References from HTML Built with Template Literals

Avatar of Chris Coyier
Chris Coyier on

One thing JavaScript template literals are great at is little blocks of HTML. Like:

// Probably from some API or whatever
const data = {
  title: "Title",
  content: "Content"
};

const some_html = `
  <div class="module">
    <h2>${data.title}</h2>
    <p>${data.content}</p>
  </div>
`;

But that’s still just a string. It’s not ready to append to the DOM just yet. And what if we need references to those elements inside somehow?

We’ve written about a couple of libraries that are in this vein: lit-html and hyperHTML. Those are pretty small libs, but are also sorta more about re-rendering of templates in an efficient way (like super mini React).

What if you just need the nodes? That’s almost a one-liner:

const getNodes = str => { 
  return new DOMParser().parseFromString(str, 'text/html').body.childNodes;
}

Now we could drop that template literal of HTML right into the DOM:

document.body.appendChild(getNodes(some_html)[0]);

Here’s that:

See the Pen pQyZOz by Chris Coyier (@chriscoyier) on CodePen.

But how do we get our hands on individual bits of that HTML? We don’t exactly have references to anything, even the whole chunk we put in.

I just saw this little lib called Facon that looks to do just this. It makes use of tagged template literals, which is super cool:

import f from 'facon';

const data = {
  title: "Title",
  content: "Content"
};

let html = f`
  <div class="module">
    <h2>${data.title}</h2>
    <p>${data.content}</p>
  </div>
`;

document.body.appendChild(html);

This skips the need for our little getNodes function, but more importantly, we can yank out those references!

let html = f`
  <div class="module">
    <h2 ref="title">${data.title}</h2>
    <p ref="content">${data.content}</p>
  </div>
`;

let { title, content } = html.collect();
title.innerText = "Title Changed!";

Here’s that:

See the Pen Facon Template by Chris Coyier (@chriscoyier) on CodePen.