load-html

include HTML code inside HTML pages using a custom tag load-html to load content dynamically

Features | Usage | API | Annotated source | License

Features

Usage

See usage example folder or read below.

Start with your index.html

<!doctype html>
<html>
  <head>
    <title>load-html usage example</title>
  </head>
  <body>
    <load-html src="helloWorld.html">Loading...</load-html>
  </body>
</html>

Content inside <load-html> custom HTML tag is optional.

Create files helloWorld.html and linkToHomepage.html in the same folder.

<!-- helloWorld.html -->

<h1>Hello World</h1>

<load-html src="linkToHomepage.html"></load-html>
<!-- linkToHomepage.html -->

<p>
  This content was loaded by <a href="https://g14n.info/load-html">load-html</a>.
</p>

Import loadHtml function some how, for example, add the following tag to your index.html:

<script src="https://unpkg.com/load-html"></script>

Then invoke it on window load, for instance add the following snippet to your index.html:

<script>
  window.addEventListener('load', function () {
    loadHtml();
  })
</script>

API

loadHtml(callback)

You can pass an optional callback function as argument:

<script>
  window.addEventListener('load', function () {
    loadHtml(function (nodes) {
      console.log('load-html nodes loaded: ' + nodes.length)
    });
  })
</script>

NOTA BENE The nodes argument passed to callback is a NodeList.

Although NodeList is not an Array, it is possible to iterate over it with forEach()

For example, using something like nodes.filter(node => !node.getAttribute('error')) will fail.

However you may want to filter those nodes that did not loaded correctly. Do something like

<script>
  window.addEventListener('load', function () {
    loadHtml(function (nodes) {
      nodes.forEach(node => {
        if (node.getAttribute('error')) {
          return
        }

        // Do something with your node...
      })
    });
  })
</script>

Annotated source

Start with attribution comment: web site and license.

// https://g14n.info/load-html
// License: MIT

Just define a global loadHtml function.

function loadHtml (callback) {

Select all <load-html /> tags. Note the loaded attribute is used to achieve recursive loading.

  var nodes = document.querySelectorAll('load-html:not([loaded])');
  var toBeLoaded = nodes.length;

Fetch the HTML content for each node.

  nodes.forEach(function (node) {
    try {
      var loader = new XMLHttpRequest();
      loader.addEventListener('load', function loadHtml () {
        if (loader.status == 200) {
          node.innerHTML = loader.responseText;
        }

Keep track of number of DOM nodes loaded, then try to repeat recursively. When done, invoke callback, if any.

        node.setAttribute('data-loaded', true);
        toBeLoaded--;

        if (toBeLoaded == 0) {
          if (typeof callback == 'function') {
            callback(nodes)
          }

          loadHtml(callback);
        }
      });

Send request to fetch content.

      loader.open('GET', node.getAttribute('src'), true);
      loader.send();

Store error, mark node as loaded.

    } catch (error) {
      console.error(error);
      node.setAttribute('data-error', error.message);
      node.setAttribute('data-loaded', true);
    }
  })
}

Export it as a global function.

window.loadHtml = loadHtml;

License

MIT