Навигация по странице
Всё чаще и чаще в web появляются сайты, использующие навигацию, написанную на JavaScript. Типичный случай использования javascript для навигации: страница с меню и блоком контента, куда через AJAX подгружается содержимое:
Пользователь кликает по пункту, JavaScript грузит из сети содержимое, вставляет в блок контента, пользователь доволен: страница без перезагрузки показывает требуемое и траффика потребовалось меньше за счёт того, что не потребовалось грузить все эти HEAD, BODY, STYLE и прочие элементы.
Но вот проблема: URL страницы. Если на old scool сайтах на каждый пункт меню показывается новая HTML страница, и у пользователя есть вменяемый URI, который он может скопировать из адресной строки бразуера, послать другу или положить в закладки, то в случае AJAX интерфейсов в URI странице зачастую нет никаких ссылок на текущий контент документа.
Пересылая ссылку из адресной строки браузера другу, пользователь не может быть уверен, откроется ли документ с тем содержимым, что он просматривает сейчас, или откроется документ с начальным содержимым страницы.
Не с секрет, что для решения этой проблемы многие программисты кодируют ссылку на текущее просматриваемое содержимое в якорь (anchor) URI документа. К примеру, на сайте jqapi.com (скриншот которого приведён вначале топика) при выборе того или иного пункта меню якорь страницы меняется на #p={contentId}.
К примеру:
jqapi.com/#p=jQuery.ajax
jqapi.com/#p=height
jqapi.com/#p=addClass
В этом случае после загрузки страницы по якорю в ссылке можно просто восстановить и показать запрашиваемое содержимое.
К сожалению, на данный момент каждый изобретает свои велосипеды для решения проблемы кодирования в якоре текущего содержимого документа. Нет единого стандарта кодирования якорей. Кроме того, разработчики зачастую забывают для чего изначально использовались якоря и лишают пользователя возможности навигации внутри документа.
Чтобы как-то решить эти проблемы к нам в голову с хабраюзером gbezyuk пришла идея создания библиотеки JSNAV, которая помогает решить указанные выше проблемы.
Как это работает?
JSNAV кодирует вызовы JavaScript обработчиков в URI документа. Для кодирования используется RFC1630 совместимые URI следующего вида:
user:pass@host:port/path/resource?query#anchor;navEventName;param1;param2;...
Cинтаксис якоря страницы:
- до служебного символа # URI страницы ничем не отличается, от указанного в стандарте, изменения касаются лишь синтаксиса якоря
- сразу же после # и до символа; идёт обычный HTML якорь со стандартным действием (прокручивание страницы до элемента якоря)
- после якоря идёт служебный символ; и указывается имя события
- далее через символ; идёт список параметров, с которыми будут вызваны обработчики событий; параметры закодированы в URL encoding в байтовой кодировке UTF-8
Библиотека после загрузки страницы начинает следить за изменениями URI по переменной window.location.href и, в случае его изменения, вызывает зарегистрированные обработчики.
JSNAV так же поддерживает работу с и обычными якорями: в случае перехода по ссылке с якорем производится scrollTo к элементу якоря. При этом в URI сохраняется описание последнего зарегистрированного события.
Обработчики представляют из себя обычные function объекты, на вход которым передаются декодированные из якоря параметры события.
var addClassHandler = function(className, textId) {
var elm = textId? document.getElementById(textId) : this;
if (elm.className && elm.className.indexOf(className) < 0) {
elm.className += " " + className;
}
}
JSNAV.bind("addClass", addClassHandler);
Обработчик addClassHandler из примера будет вызываться на URI вида:
- test.html#;addClass — вызов addClassHandler() в контексте window.document.body
- test.html#;addClass;className — вызов addClassHandler('className') в контексте window.document.body
- test.html#;addClass;className;elementId — вызов addClassHandler('className', 'elementId') в контексте window.document.body
- test.html#anchor;addClass;className — вызов addClassHandler('className') в контексте элемента якоря (элемента с id=='anchor' или name=='anchor') и прокрутка до элемента якоря
JSNAV
Библиотека написана на pure JS и, по идее, не должна конфликтовать ни с одним из известных фреймворков.
Зарепортить ошибку, предложить патч или скачать код можно на сайте проекта. Исходники доступны под Apache2 License.
Посмотреть, как всё это работает можно в примере на этой странице.
P.S.
Буду рад услышать комментарии, пожелания, получить баг-репорты. Кроме того приглашаю всех желающих присоединиться к разработке кода и документации.