SolarWind SolarWind - 2 months ago 12
CSS Question

How to load nav menu from an external file (no server, all code must be 'browser-side')?

I have a static HTML web site. I want to store the the nav (top) menu in an external file so when I change the menu, I want to see the change in all pages.

I REALLY REALLY NEED to be able to see the web pages also locally (regular Windows user, no Apache, PHP, Wamp, etc). I think Ajax won't work also.

There are two similar StackOverflow questions that partially solves this issue using PHP, SSIand ... frames. None of the solutions is good for me:


  • Frames out of discussion obviously (bad from SEO POV and also obsolete in HTML5).

  • PHP and SSI will only work after the site was uploaded on the server so it won't work locally.



The solution I see is putting ALL the menu in an external JS file. However, all the JS examples I fave found still have some 'parts' of the menu in the HTML file.

So, it is possible to have all menu in a JS file and only a call (and no actual menu items) to that file in my HTML files? I only have basic knowledge of JS. But enough to adapt a generic example for my needs.

Answer

You can have a look into HTML Imports.

Option 1: In the simplest case you can do it like that:

index.html (or any other page):

<!DOCTYPE html>
<html>
<head>
    <link rel="import" href="nav.html">
</head>
<body>
    My Page
    <script>
        var link = document.querySelector('link[rel="import"]');
        var nav = link.import.querySelector('nav');
        document.body.appendChild(nav.cloneNode(true));
    </script>
</body>
</html>

nav.html:

<nav>
    <ul>
        <li>link 1</li>
        <li>link 2</li>
        <li>link 3</li>
    </ul>
</nav>

More information at: http://www.html5rocks.com/en/tutorials/webcomponents/imports/

Option 2: Make full usage of the Web Components API and use stuff like your own HTML element, then the usage in all your files gets even easier (although the nav.html gets a little bit more complex).

index.html (or any other page):

<!DOCTYPE html>
<html>
<head>
    <link rel="import" href="nav.html">
</head>
<body>
    My Page
    <my-nav></my-nav>
</body>
</html>

nav.html

<nav>
    <ul>
        <li>link 1</li>
        <li>link 2</li>
        <li>link 3</li>
    </ul>
</nav>
<script>
    var myPrototype = Object.create(HTMLElement.prototype);
    var myDocument = document.currentScript.ownerDocument;
    myPrototype.createdCallback = function() {
        var shadow = this.createShadowRoot();
        var nav = myDocument.querySelector('nav');
        var clone = document.importNode(nav, true);
        shadow.appendChild(clone);
    };
    document.registerElement('my-nav', { prototype: myPrototype });
</script>
Comments