Ajax
Website development
HTML
27 May 2015

Сайт на основе одной HTML-страницы

Когда вокруг так много новых технологий, непросто понять, на изучение какой стоит потратить время.
(Karl Seguin)

Сейчас наступило интересное время, когда одни новые технологии стремительно меняются другими новыми, которые тоже быстро меняются. Положительная производная этого процесса в том, что, пока крутится этот технологический калейдоскоп, работа для девелопера найдётся. Но, иногда возникают задачи, для решения которых, говоря образным языком, лучше подойдёт не новая бензопила, а пилочка в старом перочинном ножике.

Изображение - Сайт на основе одной HTML-страницы

В статье показан приём разработки сайта, когда основной результат достигается за счёт использования базовых механизмов открытых стандартов.

Архитектура: Frontend, статический HTTP-сервер, XmlHttpRequest (XHR), REST.

IDE: Notepad, Notepad++ (Windows), Gedit (Linux).

Совместимость: браузер должен поддерживать JavaScript и HTML DOM.

Суть приёма


Сайт разрабатывается на основе HTML-страницы, через которую организован доступ к файлам контента. HTML-страниц, по замыслу разработчика, может быть сколько угодно, но, для достижения полной функциональности, и одной будет достаточно. В HTML-странице, ссылки на файлы контента, описываются в виде обычных HTML-ссылок, по правилам REST. За счёт расположения ссылок в одном месте, достигается ссылочная целостность.

Контент располагается в текстовых файлах и представляет собой текст, отформатированный типовой HTML-разметкой. Ограничений на расположение файлов контента нет, но будет логично, если их разместить в тематических разделах (директориях). Файлы контента не имеют связи с HTML-страницей и могут быть показаны на одной или нескольких HTML-страницах.

Сперва подгружается HTML-страница. Затем определяется и подгружается файл контента. Имя файла контента прописано в URL HTML-ссылки и определяется по правилам REST. Подгрузка файла контента осуществляется через XHR.

Ограничений никаких нет. Дизайн, код, наименования переменных и другие девелоперские соглашения — типовые для подобных разработок. Нет никакой специальной разметки, обычно применяемой для шаблонов.

Всё это немного напоминает SSI, только на Frontend-е.

Как это работает


Считать URL HTML-ссылки и определить параметры:
function getUrlParametr(parName) {
  var params = location.search.substring(1).split("&");
  for (var i = 0; i < params.length; i++) {
      if (params[i].split("=")[0] == parName) {
          return params[i].split("=")[1];
      }
  }
  return "";
}

Количество и наименование параметров определяет разработчик, главное, чтобы в HTML-cтранице, был предусмотрен функционал по их обработке.

Загрузить и отобразить контент:
function loadXMLDoc(divName, contentFile) {
  var xmlhttp=new XMLHttpRequest();
  xmlhttp.onreadystatechange = function()
  {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
    {
      document.getElementById(divName).innerHTML = xmlhttp.responseText; // отобразить контент
    }
  }
  xmlhttp.open("GET",contentFile,true);
  xmlhttp.send();
}

В параметре «id» задано расположение файла контента, которое определяется после загрузки HTML-cтраницы:
function onPageLoad() {
  var paramId = getUrlParametr("id");
  if(paramId == "")   paramId = "/xdata/news.htm"; // дефолтный контент
  loadXMLDoc("div_body",paramId);
}

<body onload='onPageLoad()'>

HTML-ссылка составлена так, что HTML-страница ссылается на саму себя, но с разными значениями параметра «id»:
<a href='site-1-page.htm?id=/it/it-box.txt'>ИТ копилка</a>

Для добавления нового контента, надо просто создать файл контента и добавить HTML-ссылку. Расширение файла контента может быть любым, но будет удобнее, если оно будет соответствовать известному MIME-типу, например «txt» или «htm». Так будет проще перенести сайт на внешний ресурс.

Это ключевые аспекты для создания информационного сайта. Интерактивность, при необходимости, может быть добавлена на основе веб-сервисов. Если же используется больше одной HTML-страницы, то можно, например, разработать одно меню для всех страниц, которое будет загружаться по тому же принципу, что и контент. Это облегчит поддержание ссылочной целостности, но расплатой будет лишний XHR запрос.

Как вместо файла контента вставить HTML-страницу


Чтобы в базовую HTML-страницу вставить другую HTML-страницу, проще всего использовать HTML-тег iframe. В этом случае XHR не нужен. В URL надо добавить ещё один параметр, например «iframe», и обрабатывать его при загрузке базовой HTML-страницы:
function onPageLoad() {
  var paramId = getUrlParametr("id");
  var paramIframe = getUrlParametr("iframe");
  if(paramId == "")   paramId = "/it/it-box.txt"; // дефолтный контент
  if(paramIframe == "" || paramIframe == "0") loadXMLDoc("div_body",paramId);
  if(paramIframe == "1") document.getElementById("div_body").innerHTML = "<iframe src='" + paramId + "'></iframe>";
}

Ключевое отличие состоит в том, что файл контента встроится в DOM базовой HTML-страницы и будет обработан единым CSS, а HTML-страница, подгруженная в iframe, нет.

Когда HTML-страница расположена не в корне


Бывает нужно разработать не весь сайт, а, например, тематический раздел. Чтобы HTML-ссылки оставались актуальными, надо учитывать путь к разделу:
  function onPageLoad(rootPath) {
    var paramId = getUrlParametr("id");
    var paramIframe = getUrlParametr("iframe");

    if(paramIframe == "" || paramIframe == 0) {
      if(paramId == "")   paramId = rootPath + "/it/it-box.txt"
      else paramId = rootPath + paramId;
      loadXMLDoc("div_body",paramId);
    }

    if(paramIframe == 1) {
      paramId = rootPath + paramId;
      document.getElementById("div_body").innerHTML = "<iframe src='" + paramId + "' width='100%' height='400'></iframe>";
    }

    if(paramIframe == 2) {
      document.getElementById("div_body").innerHTML = "<iframe src='" + paramId + "' width='100%' height='400'></iframe>";
    }
  }
}

<body onload='onPageLoad("/stencil-html-site-on-one-page")'>

Так выглядит, например, код примера к статье на GitHub-е.

Готовый шаблон


Если остались вопросы, то можно посмотреть демо сайта (GitHub) и скачать шаблон сайта (GitHub). Демо и шаблон представляют собой готовый макет и наполнены безобидным контентом.

Разработку можно вести на любом статическом HTTP-сервере, установленном локально, а потом перенести «как есть» в любое место сети.

Сильные и слабые стороны


Сильные:
  • Простота, мобильность, компактность кода.
  • Нет привязки к технологиям и БД (роль БД выполняет файловая система). В основе — только открытые спецификации и стандарты.
  • Просто создавать и сопровождать резервные копии (простым копированием).

Cлабые:
  • Frondend проигрывает Backend-у по функциональности. Сложная функциональность может оказаться значительно более трудоёмкой в разработке.
  • В браузере должен быть разрешён JavaScript.

Ссылки к статье


Архитектура REST
Типы HTTP-запросов и философия REST
XMLHTTPRequest: описание, применение, частые проблемы
Основы XMLHttpRequest
DOM: работа с HTML-страницей
JavaScript HTML DOM Document
BOM Location Object
Window.location

-24
13.2k 83
Comments 32
Top of the day