воскресенье, 27 сентября 2009 г.

Прокачка блога Blogger. Асинхронная загрузка постов.

В один прекрасный день мой знакомый попросил внедрить ему в блог http://udmitry.tumblr.com/ функционал по асинхронной дозагрузки постов в текущую страницу. В качестве эксперимента решил для начала внедрить что то похожее в свой блог. Заранее приношу извинения всем посетителям которые ощущали неудобство от моих экспериментов в конце этой недели.




Для добавления данного функционала вам понадобиться выполнить 3 шага.

Шаг 1

Для начала нам нужно найти или создать анимированную картинку которая будет отображаться при загрузке постов. Статей про создания таких картинок много, вот один из примеров "Создание анимированной GIF-картинки" с использованием Adobe Photoshop. В Adobe Photoshop я не силен, по этому воспользовался сервисом генерации картинок загрузки http://www.ajaxload.info/.

Шаг 2

На этом шаге вам необходимо добавить скрипты которые будут выполнять эти магические действия по асинхронной загрузке постов. Скрипт будет выглядеть следующем образом:

DynamicViewPost = function(settings) {
 
    default_settings = {
        older_link: "a.blog-pager-older-link",
        blog_pager: "div.blog-pager",
        blog_post: "div.blog-posts.hfeed",
        image_load_href: "ajax-loader.gif",
        error_message: "Ошибка при загрузке данных!",
        callbackOnSuccess: null,
        callbackOnError: null,
        callbackBeforCall: null
    };

    var settings = $.extend({}, default_settings, settings);
    _init();

    function _init() {
  var container = $("<div style='text-align:center'/>").appendTo(settings.blog_pager);
        DynamicViewPost.ajax_loader = $('<img id="ajax_loader" src="' + settings.image_load_href + '"/>').css("display", "none").appendTo(container); 
        $(settings.older_link).click(_click);
    };

    function _click(e) {
        if ($.isFunction(settings.callbackBeforCall)) {
            settings.callbackBeforCall();
        }
        $(settings.blog_pager + ' span > a').hide();
        DynamicViewPost.ajax_loader.css("display", "");
        $.ajax({
            url: e.target.href,
            cache: false,
            async: true,
            success: _success,
            error: _error
        });
        return false;
    }

    function _success(html) {
        var html_result = $(html);
  //Добавляем посты на страницу
        $(settings.blog_post + " > *", html_result).each(_add_to_html);
  
  //Если есть возможность загружать еще посты, меняем линк, в противном случае, удаляем секцию blog_post
  DynamicViewPost.ajax_loader.css("display", "none");
  var old_link = $(settings.older_link);
        var new_link = $(settings.older_link, html_result);
  if (new_link.length > 0) {
            old_link.attr("href", new_link[0].href).show("slow");
        }
        
  if ($.isFunction(settings.callbackOnSuccess)) {
            settings.callbackOnSuccess();
        }
    } 
 
 function _add_to_html(){
  $(this).css("display", "none").appendTo(settings.blog_post).css("display", "");
 }

    function _error() {
        settings.ajax_loader.hide("slow");
        $(settings.older_link).show("slow");
        if ($.isFunction(settings.callbackOnSuccess)) {
            settings.callbackOnSuccess();
        } else {
            alert(settings.error_message);
        }
    }
}

Добавить его в блог можно 2-я способами. Первый заключается в том что бы зайти в меню "Макет->Изменить Html" и в секции head подключить скрипты. Второй заключается в том что бы добавить еще один гаджет "HTML/JavaScript" и в нем прописать секцию подключения скриптов.

Для работы скриптов так же необходим jQuery 1.3.2

<script src='http://sscaos.googlecode.com/svn/trunk/js/jquery-1.3.2.min.js' type='text/javascript'></script> 
<script src="http://sscaos.googlecode.com/svn/trunk/js/jquery-dynamic-view-post.js" type="text/javascript"/></script>

Предполагается наличие идентификатора, строки или числа
При первом тестировании скриптов в IE получил следующую ошибку: "Предполагается наличие идентификатора, строки или числа". Оказалось что в IE при объявления словаря после последнего элемента нельзя ставить запятую.

default_settings = {
        older_link: "a.blog-pager-older-link",
        blog_pager: "div.blog-pager",
        blog_post: "div.blog-posts.hfeed",
        image_load_href: "ajax-loader.gif",
        error_message: "Ошибка при загрузке данных!",
        callbackOnSuccess: null,
        callbackOnError: null,
        callbackBeforCall: null,
    };

Ошибка при загрузке некоторых страниц
При проверки скрипта в IE посты второй страницы не подгружались, при этом асинхронная загрузка html проводилась нормально, дело было в выборе элементов

$(settings.blog_post + " > *", html_result).each(_add_to_html);

Как не странно, но в FF и других браузерах данная страница загружалась нормально, а вот в IE были проблемы. Поиск в интернете не дал решения данной проблемы, наткнулся только на описание того, что при асинхронной загрузке контента не работал выбор элементов.

Решение нашел методом "тыка", оказалось что, в одном из постов было описания кода Flex приложения без экранирования элементов "<" и ">", что приводило к сбою в IE. Добавил экранирование и все заработало!

Шаг 3

Ну и в заключении необходимо добавить скрипты по инициализации данной загрузки. Способ добавления должен быть такой же как и в "Шаг 2". В переменной image_load_href вы должны указать ссылку на вашу картинку которую вы выбрали в "Шаг 1."

<script type="text/javascript">
$(document).ready(function() {
    new DynamicViewPost({
image_load_href : "http://sscaos.googlecode.com/svn/trunk/nft/ajax-loader.gif"
});
});
</script>

После всех этих манипуляций заходим на главную страницу и вуаля, все работает! Данное решение проверено в IE7, FireFox 3.5, Safari 4, Opera 10.

4 комментария:

  1. Присоединяюсь. Где пример работы посмотреть можно :)?

    ОтветитьУдалить
  2. На этом блоге, на странице просмотра всех постов нажмите кнопку "Предыдущие".

    ОтветитьУдалить