2013 01 сентября

Полноценный мини AJAX сайт на примере Joomla 2.5 с использованием jquery и history

Никак руки не доходили, попробуем теперь.

Что получим на выходе - минималистичный сайт без привязок модулей к разным страницам и прочих "сложных" элементов, эдакий сайт визитка на полном ajax с использованием Jquery и History API (то есть в браузере кнопочки вперед\назад будут работать в полноценном режиме)

Сразу для разжигания интереса ссылка на рабочий результат

Для начала подключим в HEAD index.php шаблона Jquery (я использовал версию 1.9.1) и History API JavaScript Library v4.0.5

Далее разметка (для примера упростил)
1
23
45
67
89
10
<div id="tpl_wrapper">
        <div id="tpl_leftmenu">
                <jdoc:include type="modules" name="leftmenu" style="xhtml" />
        </div>
    <img id="ajaxloader" src="/images/ajax.gif" alt="Идет загрузка" />
        <div id="tpl_ajaxcontent">
                <jdoc:include type="message" />
                <jdoc:include type="component" />
        </div>
</div>
Немного CSS
1
23
4
/* Прелоадер загрузки данных, позиционирование на ваше усмотрение, главное в начале его скрыть */
#ajaxloader {display: none; position: absolute;  top: 20px; right: 250px; z-index: 999;}/* Скрытый див в component.php для подстановки актуального TITLE в DOM */
#tpl_ajaxtitle {display: none;}

Еще нам потребуется файл component.php в корне шаблона, он у меня такой. Собственно этот файл и отдает нам только результат работы любого компонента движка (вместе с плагинами группы content), но без модулей в данном случае.

1
23
45
67
<?php
defined('_JEXEC') or die;$doc = JFactory::getDocument();
?><div id="tpl_ajaxtitle"><?php echo $doc->title; ?></div>
<jdoc:include type="message" /><jdoc:include type="component" />

Зачем здесь tpl_ajaxtitle? Потому что я делаю в лоб скрытый див с новым титлом страницы, чтобы подменить TITLE страницы при загрузке ajax, подцепив его через Jquery ниже, аналогично можно получать и мета и прочие данные из HEAD и подменять их в нашей странице

Самое интересное в JS (камнями в мальчика не кидать, естественно код не самый оптимальный)
1
23
45
67
89
1011
1213
1415
1617
1819
2021
2223
2425
2627
2829
3031
3233
3435
3637
3839
4041
4243
44
$(document).ready(function(){
        function ajaxloadcontent(hrefFull) {            $.ajax({
                type: 'GET',            url: hrefFull+'?tmpl=component', // вызов работы через файл component.php шаблона, описан выше
            data: {},                        beforeSend: function() { // перед отправкой запроса что-то делаем
                $('#ajaxloader').fadeIn();// показали прелодер                $('#tpl_ajaxcontent').fadeOut();// скрыли блок контента
                        },                        success: function(response){ // в случае успешного выполнения запроса:
                setTimeout(function(){ // ставим паузу на 0.5 сек.                                $('#ajaxloader').fadeOut(); // убрали прелодер
                                $('#tpl_ajaxcontent').fadeIn().html(response).fadeIn(1000); // показали блок контента и подгрузили туда полученные данные (response)                                 document.title = $('#tpl_ajaxtitle').text();// Из полученного результата вычленили содержимое tpl_ajaxtitle и заменили TITLE страницы в качестве нового заголовка
                            }, 500 );                        }
                });        }
        // функция для ссылок обрабатывается при клике на ссылку        function handlerAnchors() { 
            history.pushState( null, null, this.href ); // заносим ссылку в историю            $('#tpl_leftmenu li').removeClass('active'); // для всех пунктов нашего меню убираем активность
                $(this).parent().addClass('active'); // выставляем активность для нужного            ajaxloadcontent(this.href); // запускаем функцию загрузки данных компонента
            return false;        }
        var anchors = $('#tpl_leftmenu a'); // ищем все ссылки в нашем меню         for( var i = 0; i < anchors.length; i++ ) { // по клику на ссылку запускаем событие handlerAnchors
            anchors[ i ].onclick = handlerAnchors;        }
        // вешаем событие на popstate которое срабатывает при нажатии вперед\назад в браузере        window.onpopstate = function( e ) {
            var returnLocation = history.location || document.location; // получаем нормальный объект Location            $('#tpl_leftmenu li').removeClass('active'); // снова работаем с активностью пункта меню
           var url = window.location.href;           var host = window.location.host;
                host = 'http://' + host + '/';                cururl = url.replace(host,'');
                cururl = '/'+cururl;                $('a[href$="'+cururl+'"]').parent().addClass('active'); // снова работаем с активностью пункта меню
            ajaxloadcontent(returnLocation); // загружаем контент нашей функции но уже с ссылкой из истории браузера        }
});

P.S. Сразу момент - если на сайте используются JS скрипты, подключенные в шаблоне и они не работают после загрузки контента - значит вызов нужно заново инициализировать, к примеру после success: function(response) добавить заново вызов плагина myCustomFunction();

Если есть дополнения и\или предложения по оптимизации либо более простые решения - буду рад в комментариях либо на joomlaforum

Комментарии

Недостаточно прав для комментирования