H Пишем блог с Full-Ajax навигацией сами и с нуля. Часть 1 в черновиках Из песочницы
В этой теме мы будем рассматривать реализацию full-ajax навигации на примере обычного блога. Если кому-то интересно, прошу под кат.
В очередной раз просматривая хабрахабр, меня посетила мысль наваять что-нибудь свое. Поэтому заказав пиццу и вооружившись большой кружкой чая — начал думать.
Я заметил, что на хабре много постов о том, как написать блог с использованием Fat-Free Framework, symfony, Zend и так далее… И тут у меня в голове закралась идея написать блог с ajax навигацией. А почему бы и нет? На хабре я не встретил такой статьи, может быть плохо искал…
Для того, чтобы пост не получился слишком большой я решил разделить его на несколько частей. Хочу обратить Ваше внимание на то, что это мой первый пост на хабре, да и писарь из меня никудышный. Поэтому, если что не так, извиняйте.
Ссылки в нашем блоге будут следующего вида:
http://localhost/#!/
http://localhost/#!/page
http://localhost/#!/another-apge
Такие ссылки Вы могли видеть в твиттере.
В нашей корневой директории создаем индексный файл, в котором будет немного верстки нашего кульного блога.
Я над дизайном заморачиваться не стал, так как это пост не об этом. Поэтому без комментариев выкладываю его содержание:
Мой блог v1.0
Home page About page
Единственное, на что хотелось бы обратить внимание, это яваскрипт в конце страницы, который собственно и будет инициализировать нашу ajax-навигацию по блогу.
Чуть не забыл про стили, содержимое style.css:
html, body, div, ul < margin: 0; padding: 0; >body < color: #262626; background: #f4f4f4; font: normal 12px/18px Verdana, sans-serif; >#content < position: absolute; width: 800px; right: 0px; left: 0px; margin: 40px auto 0 auto; padding: 0 60px 30px 60px; border: solid 1px #cbcbcb; background: #fafafa; -moz-box-shadow: 0px 0px 10px #cbcbcb; -webkit-box-shadow: 0px 0px 10px #cbcbcb; >h1 < margin: 30px 0 15px 0; font-size: 30px; font-weight: bold; font-family: Arial; >h1 span < font-size: 50%; letter-spacing: -0.05em; >hr < border: none; height: 1px; line-height: 1px; background: #E5E5E5; margin-bottom: 20px; padding: 0; >p < margin: 0; padding: 7px 0; >a < outline: none; >link < color: #000; text-decoration: none; >a:visited, a:link < color: #000; text-decoration: none; >a:hover < color: #000; text-decoration: none; >a:active < color: #000; text-decoration:none; >#preloader
Здесь все понятно, идем дальше… Файл ajax.js:
var ajax = < /** * Скрипт, который будет обрабатывать наши ajax запросы. */ ajSrc: 'ajax.php', ajUrl: '', /** * Функция, которая будет вызываться при начале загрузки */ onLoadStart: function()<>, /** * Функция, которая будет вызываться после получения ответа */ onLoadEnd: function()<>, /** * Мы организовали навигацию при помощи урлов вида #!/my-url. * Поэтому эта функция проверяет адресную строку на соответствие урла такому виду и в случае чего, отправляет запрос. * @return */ checkAjaxNav: function() < hash = document.location.hash; navInd = hash.substr(0, 3); if(navInd != '#!/')< this.ajUrl = hash; return false; >hash = hash.substr(2); if( hash != this.ajUrl ) < this.ajUrl = hash; this.sendData(hash); >return true; >, /** * Отправляем запрос на сервер * @param ajaxData */ sendData: function(ajaxData)< this.onLoadStart(); $.post(this.ajSrc, < ajax_data: ajaxData >, function( data )< ajax.receiveData(data); >, 'json'); >, /** * Получаем ответ от сервера и обрабатываем его. * @param data */ receiveData: function( data ) < for( var key in data )< var val = dataPhp cms with ajax; if( 'eval' == key ) eval(val); else $(key).html(val); >this.onLoadEnd(); >, /** * Инициализируем нашу навигацию */ init: function()< this.checkAjaxNav(); $(window).bind('hashchange', function()< ajax.checkAjaxNav(); >); > >;
Здесь видно, что мы будем отправлять запросы функцией sendData() на наш обработчик ajax.php .
Перед тем, как запрос будет отправлен, вызывается функция onLoadStart() в которой можно выполнять что-то. Например показать пользователю красивый индикатор загрузки, прикрутить валидацию форм и т.д.
После того, как наш запрос будет обработан, вызывается функция receiveData() , в которой мы обрабатываем полученные данные и вызываем функцию onLoadEnd() , которая скрывает наш индикатор загрузки и выполняет какие-то другие функции. Например, ре-инициализация форм страницы и т.д
receiveData(); switch($ew[1]) < case 'about': $html['#posts'] = $blog->sendData($html); > ?>
Это небольшой контролер, который будет обрабатывать наши запросы и данные. Пока что здесь нет ничего сверх естественного.
Функция receiveData() получает данные POST-запроса. А sendData() отправляет данные. Сейчас это только json, но дальше мы прикрутим еще что-нибудь.
Данные мы будем отправлять массивом, в котором ключом будет выступать селектор элементов или #id элемента на конечной странице, а значением — некие данные.
Так же этой функцией мы можем отправлять js код, который затем выполнится на странице при помощи eval()
Пример для наглядности:
$arr = array(); $arr['#first_div'] = "First div content"; $arr['#second_div'] = "Second div content"; $arr['.another_divs'] = "Content that will be placed to several divs"; $blog->sendData($arr, "alert('Hello world !');");
$data = $_POST['ajax_data']; $data = explode('/', $data); unset( $_POST['ajax_data'] ); return $data; > /** * @param $data * @param string $eval * @return bool */ public function sendData( $data, $eval = '' ) < if(!$data && !$eval) return false; if( !headers_sent() )< header('Content-Type: application/json; charset=utf-8' ); >echo json_encode( array_merge($data, array('eval' => $eval)) ); return true; > >
- Организация БД для хранения постов, комментариев
- Обработчик форм
- * Допиливание существующего функционала
- Оптимизация кода
В качестве БД можно расмотреть такие варианты как традиционная MySQL, или MongoDb.
* Планируется добавление xml и plain типов данных.
Если у Вас есть какие-либо пожелания, о том, что бы Вы хотели видеть в следующей статье — пишите.
Если у Вас есть свое мнение, по поводу того, что и как можно было бы сделать лучше — пишите, буду рад.
Так же рад буду и конструктивной критике.