Судя по комментариям в этой статье, создание веб-приложений с возможностью аякс-навигации является интересной для сообщества темой и пока еще немногие сталкивались с подобной задачей. Я расскажу о ее решении с помощью небольшой библиотеки под названием jQuery-Pjax (либо моего форка ее).
Моя мотивация: в проекте нужно было реализовать mp3-плеер, играющий независимо от навигации на сайте. Далее потребовалось добавить поддержку браузеров без pushState — и я сделал форк библиотеки.
Основа — раздельный вывод и кеширование обычных запросов и запросов со специфическими заголовками. То есть, в контроллере перед выводом шаблона страницы, необходима проверка наличия заголовка X-PJAX, например, так:
PHP:
Далее, на ссылки подвешивается событие, которое передает управление навигацией яваскрипту (это самая радужная и ненавязчивая реализация — а особого смысла в других я не вижу). В моем случае есть нечто вроде:
Для обработки форм мы используем:
Но вы, конечно, можете использовать определенный класс или атрибут data-pjax для выборки ссылок.
Также есть два полезные события:
Более подробную информацию о Pjax вы найдете в README.md на github.
К создателю библиотеки несколько раз обращались с просьбой добавить поддержку хешей, но его позиция оказалась принципиальной ( github.com/defunkt/jquery-pjax/issues/3#issuecomment-986233, github.com/defunkt/jquery-pjax/issues/3#issuecomment-1353555, github.com/defunkt/jquery-pjax/issues/3#issuecomment-1354589). Потому я слегка модифицировал ее, добавив автоматический переход на #!/хеши и свободную конвертацию адресов двух типов.
Однако, в моей модификации необходимо указать два параметра:
Таким образом мы в несколько строк кода реализуем одностраничное веб-приложение. Буду благодарен за комментарии и любые багтреки.
Feel free to fork and roll your own © defunkt
Спасибо Terion за наводку.
=>
Работа над этим проектом оказалась крайне познавательной — потому есть, что рассказать еще. В следующей статье я напишу о создании многофункционального аудио-видео плеера с плейлистом на основе jPlayer (http://jplayer.org/).
Восклицательный знак — специальный сигнал для поисковиков, что этот контент может быть доступен и другими путями. Без него хеш-навигация для поисковика действительно превращается в чёрный ящик.
Не совсем так.
Используется дополнительный урл для обработки, см спеку и изначатьльную инициативу.
И да, вроде бы пока это только гугл.
Я не использовал этот функционал, только читал.
Моя мотивация: в проекте нужно было реализовать mp3-плеер, играющий независимо от навигации на сайте. Далее потребовалось добавить поддержку браузеров без pushState — и я сделал форк библиотеки.
Основные особенности
- навигация по сайту и обработка форм без полной перезагрузки страниц
- чистые url, доступные для прямого доступа
- поддержка #!/hash для устаревших браузеров (добавлено в моей версии)
- работа с кнопками «назад» и вперед» для современных браузеров
- а теперь и для старых — благодаря benalman.com/projects/jquery-hashchange-plugin
похоже, есть проблемы с ИЕ7 (спасибо Nc_Soft)(тем более, большое спасибо за участие Nc_Soft)и, возможно, opera 11.5 (пока не могу подтвердить, но нахожу крайне удивительным из-за dev.opera.com/articles/view/introducing-the-html5-history-api) — сообщение artishok— проверено и работает на сборке 1074 (not_ice)- imsamurai (https://github.com/imsamurai) предложил улучшения библиотеки (и я радостью слил изменения): встроенная функция для отправки форм, улучшения работы с хешами и более развитая система триггеров. (у imsamurai, к сожалению, нет аккаунта на хабре — будем рады помощи)
Ссылки
- jQuery Pjax github.com/defunkt/jquery-pjax
- мой форк с поддержкой хеш-навигации github.com/ckald/jquery-pjax
- работа библиотеки на примере моего проекта amsterdamusic.com.ua
- пример от создателя pjax.heroku.com
Принцип работы Pjax
Основа — раздельный вывод и кеширование обычных запросов и запросов со специфическими заголовками. То есть, в контроллере перед выводом шаблона страницы, необходима проверка наличия заголовка X-PJAX, например, так:
PHP:
if (!isset($_SERVER['HTTP_X_PJAX'])
{ // here is regular-kind load }
else
{ // here you don't print page layout — just the page }
Далее, на ссылки подвешивается событие, которое передает управление навигацией яваскрипту (это самая радужная и ненавязчивая реализация — а особого смысла в других я не вижу). В моем случае есть нечто вроде:
$('#pjaxcontainer a:not(.logout-link,.login-link,.login_link,[id*="login_link"],[href*="#"],[target="_blank"],'
+'[href$="mp3"],[href$="jpg"],[href$="jpeg"],[href$="gif"],[href$="png"],[href$="doc"],[href$="pdf"])')
.pjax('#pjaxcontainer', {
timeout: 0
});
Для обработки форм мы используем:
$('#pjaxcontainer form').live('submit',function(a){
// display loading message
$('#loading-shade').show();
if( !$(a.target).attr('action'))
a.target = $(a.target).closest('form');
data = $(a.target).serialize();
cont = $('#pjaxcontainer');
$.ajax({
type: "POST",
url: $(a.target).attr('action'),
data: data,
beforeSend : function(xhr) {
return xhr.setRequestHeader('X-PJAX','true'); // IMPORTANT
},
success: function(msg){
cont.html(msg);
$('#loading-shade').hide();
},
error: function(a,b,c) {
$('#loading-shade').hide();
}
});
a.preventDefault();
return false;
});
Но вы, конечно, можете использовать определенный класс или атрибут data-pjax для выборки ссылок.
Также есть два полезные события:
$('body').bind('start.pjax',function() {
setTimeout("$('#loading-shade').hide();",2000); // to be sure that loading message hides
$('#loading-shade').show();
});
$('body').bind('end.pjax',function() {
$('#loading-shade').hide();
});
Более подробную информацию о Pjax вы найдете в README.md на github.
Допиливание хеш-навигации
К создателю библиотеки несколько раз обращались с просьбой добавить поддержку хешей, но его позиция оказалась принципиальной ( github.com/defunkt/jquery-pjax/issues/3#issuecomment-986233, github.com/defunkt/jquery-pjax/issues/3#issuecomment-1353555, github.com/defunkt/jquery-pjax/issues/3#issuecomment-1354589). Потому я слегка модифицировал ее, добавив автоматический переход на #!/хеши и свободную конвертацию адресов двух типов.
Однако, в моей модификации необходимо указать два параметра:
$.siteurl = 'http://yousite.com';
$.container = '#pjaxcontainer';
Заключение
Таким образом мы в несколько строк кода реализуем одностраничное веб-приложение. Буду благодарен за комментарии и любые багтреки.
Feel free to fork and roll your own © defunkt
Спасибо Terion за наводку.
=>
Планы
Работа над этим проектом оказалась крайне познавательной — потому есть, что рассказать еще. В следующей статье я напишу о создании многофункционального аудио-видео плеера с плейлистом на основе jPlayer (http://jplayer.org/).
Важные комментарии
Devgru, 12 июля 2011, 20:43 #
Восклицательный знак — специальный сигнал для поисковиков, что этот контент может быть доступен и другими путями. Без него хеш-навигация для поисковика действительно превращается в чёрный ящик.
Devgru, 12 июля 2011, 23:29 #
Не совсем так.
Используется дополнительный урл для обработки, см спеку и изначатьльную инициативу.
И да, вроде бы пока это только гугл.
Я не использовал этот функционал, только читал.