Пишем блог с Full-Fjax навигацией сами и с нуля. Часть 1

от автора

Всем привет.

В этой теме мы будем рассматривать реализацию full-ajax навигации на примере обычного блога. Если кому-то интересно, прошу под кат.

В очередной раз просматривая хабрахабр, меня посетила мысль наваять что-нибудь свое. Поэтому заказав пиццу и вооружившись большой кружкой чая — начал думать.
Я заметил, что на хабре много постов о том, как написать блог с использованием Fat-Free Framework, symfony, Zend и так далее… И тут у меня в голове закралась идея написать блог с ajax навигацией. А почему бы и нет? На хабре я не встретил такой статьи, может быть плохо искал…
Для того, чтобы пост не получился слишком большой я решил разделить его на несколько частей. Хочу обратить Ваше внимание на то, что это мой первый пост на хабре, да и писарь из меня никудышный. Поэтому, если что не так, извиняйте.

Итак, приступим.

Демо.

Ссылки в нашем блоге будут следующего вида:

http://localhost/#!/
http://localhost/#!/page
http://localhost/#!/another-apge

Такие ссылки Вы могли видеть в твиттере.

В нашей корневой директории создаем индексный файл, в котором будет немного верстки нашего кульного блога.
Я над дизайном заморачиваться не стал, так как это пост не об этом. Поэтому без комментариев выкладываю его содержание:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head>     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />     <meta name="description" content="" />     <meta name="keywords" content="" />     <meta name="generator" content="" />     <title>My thirst Ajax Blog</title>     <script type="text/javascript" src="inc/ajax.js"></script>     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>     <link type="text/css" rel="stylesheet" href="style.css"/> </head> <body>     <div id="content">         <h1><a href="/#!/">Мой блог</a> <span>v1.0</span></h1>         <p>             <a href="/#!/">Home page</a>             <a href="/#!/about">About page</a>         </p>         <hr />         <div id="posts"></div>     </div>     <div id="preloader">         <div style="position: absolute; left: 50%; margin-left: -50px; top: 50%; margin-top: -50px;">                 <img src="loading.gif" title="Loading..." alt="Loading.." />         </div>     </div> </body> <script>     $(document).ready(function(){         ajax.onLoadStart = function(){             $('#preloader').show();         };         ajax.onLoadEnd = function(){             $('#preloader').hide();         };         ajax.init();     }); </script> </html>  

Единственное, на что хотелось бы обратить внимание, это яваскрипт в конце страницы, который собственно и будет инициализировать нашу 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{     display: none;     position:fixed;     z-index: 777;     background:none repeat scroll 0 0 #000000;     cursor:wait;     width:100%;     height:100%;     top:0;     left:0;     opacity:0.7;     -moz-opacity: 0.5;     -khtml-opacity: 0.5; } 

Здесь все понятно, идем дальше… Файл ajax.js:

var ajax = {      /**      * Скрипт, который будет обрабатывать наши ajax запросы.      */     ajSrc: 'ajax.php',     ajUrl: '',     /**      * Функция, которая будет вызываться при начале загрузки      */     onLoadStart: function(){},     /**      * Функция, которая будет вызываться после получения ответа      */     onLoadEnd: function(){},      /**      * Мы организовали навигацию при помощи урлов вида #!/my-url.      * Поэтому эта функция проверяет адресную строку на соответствие урла такому виду и в случае чего, отправляет запрос.      * @return {Boolean}      */     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 = data[key];             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(), которая скрывает наш индикатор загрузки и выполняет какие-то другие функции. Например, ре-инициализация форм страницы и т.д

Обработчик ajax.php

<?php error_reporting(0);  define("coolBlogCms", true); define("DIR", getcwd() . "/"); define("INC", DIR . "inc/");  require_once INC . "myAjax.php";  $blog = new myAjax();  if( isset($_POST['ajax_data']) ){     $ew = $blog->receiveData();      switch($ew[1]){         case 'about':             $html['#posts'] = <<<HTML     This is about page. Loaded from my ajax cms. HTML;             break;         default:             $html['#posts'] = <<<HTML     This is the main page of my cool blog. Thank's for reading. HTML;              break;     }      $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 !');"); 

myAjax.php

<?php  if(!defined("coolBlogCms"))     exit;  class myAjax{      /**      * @return bool      */     public function receiveData(){         if( !isset($_POST['ajax_data']) ){             return false;         }          $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 типов данных.

Если у Вас есть какие-либо пожелания, о том, что бы Вы хотели видеть в следующей статье — пишите.
Если у Вас есть свое мнение, по поводу того, что и как можно было бы сделать лучше — пишите, буду рад.

Так же рад буду и конструктивной критике.

ссылка на оригинал статьи http://habrahabr.ru/post/210402/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *