На днях мне пришлось разрабатывать сайт, в котором необходимо было сделать AJAX навигацию на Mootools. Естественно, нужно было сохранить возможность добавлять ссылки на страницы сайта в закладки и также сохранить поддержку кнопок Назад/Вперед в браузере. В общем типичная проблема для AJAX приложений. Ранее я писал, как сделать History при помощи YUI, однако, мне желательно было сделать все в Mootools, поэтому пришлось искать решения для этой библиотеки. После некоторых поисков я все же нашел подходящий скрипт на digitarald.de, совместимый со всеми основными браузерами (Internet Explorer 6+, Opera 9, Firefox 1.5+, Safari 2+), однако он написан под Mootools 1.11. Этот же скрипт, но переделанный под новую версию (Mootools 1.2), я нашел на aNobii Blog. Однако он тоже отказался работать, поэтому пришлось его немного переделать. В результате я получил вполне работоспособный скрипт, которым хочу поделиться с вами. Скачать его можно здесь.
Теперь о том как им пользоваться.
Самым первым шагом, конечно же является подключение скрипта в страницу:
<script src="mootools-1.2.js" type="text/javascript"></script> <script src="HistoryManager12.js" type="text/javascript"></script>
После этого, на странице будет доступен объект HistoryManager, который собственно и будет выполнять основную работу. Первое, что нужно здесь сделать, это инициализировать этот объект:
HistoryManager.initialize();
Следующий шаг - регистрация модуля (этот пример взят из класса PaginationClass, полный вариант которого приведен в конце статьи):
this.historyKey = 'ajax_';
this.history = HistoryManager.register(
this.historyKey,
[firstPage],
function(values) {
this.to(values[0]);
}.bind(this),
function(values) {
return [this.historyKey, values[0]].join('');
}.bind(this),
this.historyKey + '(.+)'
);
Кажется сложным, но это лишь на первый взгляд, к этому можно быстро привыкнуть :). После выполнения этой функции, мы получим объект this.history, который будет иметь следующие функции: setValues(), setValue(), generate() и unregister(). Теперь о параметрах функции register(). Первый параметр - this.historyKey - уникальный ключ модуля (можно регистрировать одновременно несколько модулей, поэтому и необходимо, чтобы они были уникальными).
Второй параметр это страницы по умолчанию; метки, указанные в этом массиве, будут добавлены в стек объекта HistoryManager. В моем примере, я добавляю в этот параметр первую страницу, на которую нужно перейти сразу после загрузки. Третий параметр - callback onMatch, который вызывается при изменении состояния (при вызове setValue()). Четвертый параметр - callback onGenerate, который должен возвращать строку для хэша (url после знака решетки). И последний параметр - регулярное выражение для хэша.
Теперь, при изменении состояния страницы, необходимо устанавливать “отметку” в истории, чтобы можно было потом вернуться, делается это так:
this.history.setValue(0, value);
0 - это индекс страницы, value - это отметка для истории.
В самом конце, после регистрации всех модулей, нужно вызвать функцию start():
HistoryManager.start();
Пример приложения
Итак, рабочий пример приложения написанного при помощи скрипта HistoryManager. Приложение будет просто выполнять навигацию с одной страницы на другую при помощи AJAX.
Шаг 1: HTML
HTML для страницы очень прост - сайдбар со ссылками и контейнер, в котором будет размещаться содержимое сайта (полчаемое через AJAX):
<!-- ссылки --> <ul id="sidebar"> <li><a href="yuihist1.html">Страница 1</a></li> <li><a href="yuihist2.html">Страница 2</a></li> <li><a href="yuihist3.html">Страница 3</a></li> </ul> <!-- контейнер для отображения полученных от сервера данных --> <div id="container"></div>
Шаг 2: CSS
#header {
text-align: center;
background: #ccc;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
#sidebar {
width: 240px;
float: left;
}
#sidebar li {
list-style-type: none;
}
#container {
width: 440px;
height: 400px;
padding: 8px;
border: 1px solid #aaa;
float: left;
overflow: auto;
}
Шаг 3: JavaScript
Ну и последнее, наш скрипт:
window.addEvent('domready', function(){
HistoryManager.initialize();
// устанавливаем в первоначальную позицию
var firstPage = '/demo/moohistory/yuihist1.html';
var pagi = new PaginationClass(firstPage);
$$('a').addEvent('click', function(e) {
e.stop();
pagi.to(this.href);
});
HistoryManager.start();
});
var PaginationClass = new Class({
initialize: function(firstPage) {
this.historyKey = 'ajax_';
this.history = HistoryManager.register(
this.historyKey,
[firstPage],
function(values) {
this.to(values[0]);
}.bind(this),
function(values) {
return [this.historyKey, values[0]].join('');
}.bind(this),
this.historyKey + '(.+)'
);
},
to: function(page) {
if (page === undefined || page === null /*|| dCond*/) return;
page = page.replace(/^http:\/\/[^\/]+/, '');
this.page = page;
var req = new Request.HTML({url:page,update:'container'}).get(page);
this.history.setValue(0, this.page);
}
});
Как видите, для навигации я использовал упомянутый выше класс PaginationClass. При инициализации этого класса вызывается одна единственная функция register(), описанная выше. Вторая функция - to() выполняет AJAX запрос и устанавливает отметку в history.
В самом же начале скрипта (который выполняется при событии domready) инициализируется объект HistoryManager и назначается обработчик событий для ссылок в сайдбаре. В итоге, при щелчке на ссылках, будет получаться атрибут href и далее, функция PaginationClass.to() будет обновлять содержимое контейнера и устанавливать соответствующую точку в истории.
Посмотреть этот пример в действии можно по следующей ссылке:
Еще более совершенный демо пример можно найти на сайте автора этого чудесного скрипта: