JavaScript виджет: бесконечная загрузка твитов

Владимир | | CSS, HTML, JavaScript, Web разработка.

load on scroll

В последнее время я часто замечаю на различных сайтах виджеты, которые подгружают контент при определённых действиях посетителя. Такой подход позволяет с одной стороны, сократить количество данных на странице, а с другой – при необходимости показывать практически неограниченный объем информации.

Рассмотрим небольшой практический пример.

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

На первый взгляд всё предельно просто, twitter предоставляет API, с помощью которого можно получить твиты любого пользователя (если они открыты). Вставить их сайдбар тоже не проблема.

Но на практике возникает несколько интересных моментов.

1) Информация от twitter не является основным контентом сайта и не должна влиять на скорость загрузки страницы. Кроме того, доступность сервиса также не должна влиять на работу сайта.

2) Твиты могут появляться довольно быстро, поэтому чтобы информация в виджете была всегда актуальной от кеширования придётся отказаться.

3) Т.к. твиты не являются основным содержимым страницы, то посетитель скорее всего не заметит если они появятся через некоторое время после загрузки основной части страницы.

4) Не ясно, сколько именно твитов нужно выводить. Части посетителей эта информация будет не интересна вообще, но пользователи этого сервиса, возможно, захотят прочитать несколько десятков сообщений.

5) Количество места, выделенного под виджет, обычно ограничено. И необходимо чтобы загрузка новых твитов не «ломала» дизайн.

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

Теперь рассмотрим сам виджет.

Начнём с алгоритма.

1) Создаём на странице область с фиксированной высотой и вертикальным полосой прокрутки.

2) После загрузки страницы подгружаем в эту область твиты с помощью JavaScript.

3) Если пользователь переместит ползунок скролла в крайнее нижнее положение – загружаем следующую «порцию» твитов.

Посмотреть как работает такой виджет можно на демонстрационной страничке. И сразу же даю ссылку на архив с этим примером.

Source

Разметка виджета с твитами может выглядеть следующим образом.

<div id="tweets">
    <div class="loader hidden"></div>
</div>

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

.loader {
    background-image: url('ajax-loader.gif');
    width: 400px;
    height: 300px;
    background-repeat: no-repeat;
    background-position: center center;
    position: fixed;
}

Значения width и height должны совпадать с соответствующими значениями, установленными для виджета (div#tweets).

#tweets {
    height: 300px;
    width: 400px;
    overflow: auto;
    position: relative;
    border: solid 1px #999;
    margin: 3em auto 0 auto;
}

Переходим к загрузке твитов

Основная сложность заключается в том, что нам нужно с помощью JavaScript выполнить кросс-доменный запрос к серверу twitter’а. Такие запросы запрещены политикой безопасности браузеров, поэтому использовать обычный AJAX запрос не получится.

Тем не менее, благодаря тому, что Twitter API поддерживает JSONP задача решается достаточно просто.

$(function() {
    //параметры для получения твитов
    var user_id = '24147920';
    var tweets_url = 'http://api.twitter.com/1/statuses/user_timeline.json';
    var page = 1;
    var tweets_num = 10;
    
    //список твитов и картинка загрузчика
    var container = $('#tweets');
    var loader = $('.loader');
    
    //шаблон для поиска ссылок в твитах (упрощенный)
    var pattern = /(http\S+)/gi;
    
    //загружаем первую страницу твитов
    get_tweets(page);
    
    //обработчик события scroll
    container.scroll(function() {
        //это условие выполняется когда ползунок находится в крайнем нижнем положении
        if  (container[0].scrollTop == container[0].scrollHeight - container[0].clientHeight){
            //показываем загрузчик
            loader.removeClass('hidden');
            //загружаем очередную страницу твитов
            page = page + 1;
            get_tweets(page);
        }
    });
    
    //эта функция загружает твиты, ищет ссылки и ставит для них
    //соответствующий тег <a href="...">, вставляет твиты в список
    function get_tweets(page) {
        $.getJSON(
            //формируем запрос на получение твитов (используется JSONP)
            tweets_url + '?user_id=' + user_id + '&page=' + page + '&count=' + tweets_num + '&callback=?',
            function(data) {
                $(data).each(function(i, tweet) {
                    //формируем ссылки
                    var text = tweet.text.replace(pattern, '<a href="$1" target="_blank">$1</a>');
                    //вставляем твит в список
                    container.append('<div class="tweet">' + text + '</div>');
                });
                //прячем загрузчик
                loader.addClass('hidden');
            }
        );
    }
});

Прежде всего, мы подготавливаем данные, которые нужны для работы с Twitter API (строки 3-6). Для данного примера я использовал свою собственную ленту твитов, но вы можете вывести любую другую. Также не принципиально сколько твитов загружать за раз, главное, чтобы после первоначальной загрузки появилась полоса прокрутки.

Для получения твитов используем метод getJSON (строки 33-46, библиотека jQuery).

В первом её параметре передаём запрос на получение твитов. В него мы включаем:
— id пользователя ('?user_id=' + user_id);
— номер страницы ('&page=' + page);
— количество твитов на странице ('&count=' + tweets_num);
— имя функции, которая будет вызвана после получения данных ('&callback=?') – его jQuery формирует автоматически и подставляет вместо знака вопроса.

После получения твитов нам остается только добавить их в список (строки 36-42). При этом, мы ищем ссылки в тексте твитов и обрамляем их тегом <a>.

Завершающий этап – установка обработчика для события scroll (строки 19-28).

Здесь нужно только проверить достигнут конец списка или нет. Если достигнут, показываем загрузчик (убираем класс hidden) и вызываем функцию get_tweets, которой передаём номер нужно страницы. В противном случае, не делаем ничего.

Всё. Можно считать, что виджет в рабочем состоянии. Конечно, перед размещением на рабочем сайте нужно будет его немного доработать, например, добавить вывод сообщение об ошибке при отсутствии доступа к twitter'у. Но, думаю, с этой задачей вы легко справитесь сами 😉

Успехов!

Интересное

Глянцевая и матовая печать фотокниг и свадебных фотоальбомов

Любителям страйкбола будет интересно почитать про камуфляж Горка его расцветки и разновидности.