Как загрузить навигационное меню из внешнего файла? (Нет Wamp, весь код должен быть "браузером" )

У меня есть статический веб-сайт HTML. Я хочу сохранить навигационное (верхнее) меню во внешнем файле, поэтому, когда я меняю меню, я хочу увидеть изменение на всех страницах.
Я ДЕЙСТВИТЕЛЬНО НУЖДАЮТСЯ, что вы можете видеть веб-страницы также локально (обычный пользователь Windows без необходимости устанавливать дополнительное программное обеспечение: Apache, PHP, Wamp, определенные браузеры и т.д.).

Есть два похожих вопроса StackOverflow, которые частично решают эту проблему с помощью PHP, SSI и... frames. Ни одно из решений не подходит для меня:

  • Рамки из обсуждения явно (плохо от SEO POV, а также устарели в HTML5).
  • PHP и SSI будут работать только после того, как сайт будет загружен на сервер, чтобы он не работал локально.

Решение, которое я вижу, представляет собой ВСЕ меню во внешнем JS файле. Тем не менее, все примеры JS, которые я нашел, все еще имеют некоторые "части" меню в файле HTML.

Итак, возможно ли иметь все меню в JS файле и только вызов (и никаких фактических пунктов меню) в этот файл в моих HTML файлах? У меня есть только базовые знания JS. Но достаточно, чтобы адаптировать общий пример для моих потребностей.

Ответ 1

menu.html

<ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="active1.html">Contact</a></li>
    <li><a href="active2.html">About</a></li>
    <li><a href="active3.html">Portfolio</a></li>
</ul>

index.html

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

<div id="nav"></div>

js файл:

$(function() {

    $("#nav").load("menu.html");

    function activeNav() {
        var pgurl = window.location.href.substr(window.location.href.lastIndexOf("/")+1);
         $("#nav ul li a").each(function(){
              if($(this).attr("href") == pgurl || $(this).attr("href") == '' )
              $(this).addClass("active");
         });
    }

    setTimeout(function() {
        activeNav();
    }, 100);

});

SetTimeout позволяет загружать страницу, а затем запускает функцию, чтобы увидеть, какая ссылка активна, и затем вы можете добавить класс в css:

#nav ul li a.active {
        color: #ff0000;
        font-weight: bold;
    }

Ответ 2

nav.html//вам не нужно размещать html, body или т.д. Только сам nav.

<nav> bla bla </nav>

index.html

<!doctype html>
<html>

  <head>
    <title>onload test</title>
    <script>

    window.onload = function(){
    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function(){
        if(this.readyState == 4 && this.status == 200){
             document.getElementById('includeNav').innerHTML= '<object type="text/html" data="nav.html"></object>';
        }
    }

    xhttp.open('POST', 'nav.html', true); // method, location, async
    xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhttp.send(); }
    </script>
  </head>


  <body>
    <p>The load event fires when the document has finished loading!</p>
    <div id="includeNav"></div>
  </body>
</html>

ПОПРОБУЙТЕ это. это может быть ответом на ваш вопрос.

Ответ 3

Вы можете просмотреть HTML-импорт.

Вариант 1: В простейшем случае вы можете сделать это следующим образом:

index.html(или любая другая страница):

<!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>

Дополнительная информация: http://www.html5rocks.com/en/tutorials/webcomponents/imports/

Вариант 2: Полностью используйте API веб-компонентов и используйте такие вещи, как ваш собственный HTML-элемент, а затем использование во всех ваших файлах становится еще проще (хотя nav.html получает немного более сложный).

index.html(или любая другая страница):

<!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 navProto = Object.create(HTMLElement.prototype);
    var navDoc = document.currentScript.ownerDocument;
    navProto.createdCallback = function() {
        var shadow = this.createShadowRoot();
        var nav = navDoc.querySelector('nav');
        var clone = document.importNode(nav, true);
        shadow.appendChild(clone);
    };
    document.registerElement('my-nav', { prototype: navProto });
</script>

EDIT: Заметным недостатком обоих решений является поддержка браузера:

В основном это Chrome (включая Android) и Opera, которые поддерживают эти функции. К сожалению, невозможно использовать импорт HTML без веб-сервера из-за настроек безопасности браузера. Вы получите консольную ошибку:

Imported resource from origin 'file://' has been blocked 
from loading by Cross-Origin Resource Sharing policy: 
Invalid response. Origin 'null' is therefore not allowed access.

Таким образом, вам нужно будет запустить простой веб-сервер, например, модуль nodejs http-server, или использовать расширение Chrome, такое как редактор Chrome Dev, который создает встроенный веб-сервер https://chrome.google.com/webstore/detail/chrome-dev-editor/pnoffddplpippgcfjdhbmhkofpnaalpg?utm_source=chrome-app-launcher-info-dialog

Ответ 4

Копия ответа на другой поток:

Я думаю, что это самый простой способ сделать это без серверного языка. Используйте библиотеку javascript, например W3Data. Все, что вам нужно сделать, это добавить атрибут w3-include-html в ваш div. Готово!

Если ваше меню находится в файле menu.html, вы бы сделали что-то вроде этого.

<div w3-include-html="menu.html"></div> 

Ответ 5

Вы можете использовать JsRender/JsViews для этого.