Блог Михаила Крамера. PHP и JS
jScroll. Бесконечная прокрутка без особых проблем и дружественная к поисковикам

Итак, заказчик попросил на сайте, где уже была сделана традиционная пагинация, сделать т.н. бесконечную прокрутку - т.е. чтоб при скроллинге до конца страницы подгружались данные со следующих страниц. Ничего сложного, но переписывать код было лень. И тут на помощь пришёл скриптик jScroll

Итак, мы имеем в начале примерно следующий код php:


// Естественно, предполагается, что переменные для доступа к БД, а также различные другие, неопределённые здесь
// функции описаны ранее, и делают то, что полагается
$db = new mysqli($db_host, $db_user, $db_pass, $db_name);

$total_pages   = get_total_pages(); // Предположительно функция вернёт кол-во страниц
$current_page = isset($_GET["page"]) ? (int) $_GET["page"] : 1;
$offset        = get_offset($current_page, $total_pages); // Рассчитает смещение относительно страницы - алгоритм очень известный и простой

$data = get_data($offset); // Получаем данные для текущей страницы. Положим, уже готовую вёрстку данных

echo "<div class='content'>";
echo $data;

echo "<div class='pagination'>";
// Ну и традиционно рисуем страницы
for ($i = 1; $i <= $total_pages; $i++)
   echo "<a href='?page=$i'>$i</a>&nbsp;&nbsp;";
echo "</div>";
echo "</div>";

Как видите, совершенно традиционный код вывода пагинированных данных. Теперь мы хотим, чтоб у нас был бесконечный скроллинг. И мы будем использовать jScroll. Давайте рассмотрим настройки его скрипта. Они есть на официальном сайте, а здесь я приведу небольшой перевод:

Опция Значение по умолчанию Описание
debug false Если true, выводит отладочную инфу в консоль браузера
autoTrigger true Если true, автоматом загружает контент, когда пользователь прокручивает страницу до конца заданного блока
autoTriggerUntil false Позволяет отключить автоматическую подгрузку после определённого количества страниц
loadingHtml '<small>Loading...</small>' Код, который будет отображаться вместо будущего содержимого в процессе загрузки
padding 0 Отступ от нижней границы уже загруженного контента до вновь загруженного. Требует autoTrigger=true
nextSelector 'a:last' Селектор ссылки, из которой будет браться адрес для подгрузки следующей страницы. Если вновь загруженный код не содержит такого селектора, объект jScroll автоматически уничтожается
contentSelector '' Селектор для блока, который будет вырезан из подгруженной страницы. Если нет - будет вставлен весь DOM подгруженной страницы. См. документацию jQuery.load
callback false Функция, которая будет вызвана после подгрузки и размещения нового контента на страницу

Итак, прочитав параметры и посмотрев примеры на странице плагина, можно составить представление о том, что нам нужно для переделки. И на самом деле, нужно совсем немного - добавить в код ссылку на следующую страницу. Теперь по поводу SEO. Для поисковых роботов я бы оставил традиционную пагинацию. Также я бы не стал её убирать, поскольку есть небольшая вероятность, что к нам зайдёт человек без javascript. И тут мы используем распространённый приём - просто из кода js спрячем этот блок для всех остальных. Этот же код нужно будет вызывать каждый раз после подгрузки страницы - ведь они все будут содержать пагинацию. Поэтому строку 19 предыдущего кода заменим на следующий:


if ($currrent_page != $total_pages)
   echo sprintf("<a class='jscroll_next' href='?page=%d'></a>", $current_page + 1);

Теперь осталось дописать соответствующий javascript:


function hide_pagination() {
    // Прячем пагинацию
    $(".pagination").hide();
}
$(function () {
    hide_pagination();
    if ($("a.jscroll_next").length != 0)
        $('#a_list').jscroll({contentSelector: "#content>*", nextSelector: "a.jscroll_next:last", callback: hide_pagination});
});

Если вы внимательно ознакомились с предыдущим кодом и документацией, большая часть js для вас должна быть очевидна. Обратите внимание на contentSelector - если не указать >*, jQuery.load вставляет не содержимое указанного блока, а весь указанный блок. Если нам нужно содержимое, это необходимо указать явно, как это сделал я. Некоего пояснения требует только строка 7. Дело в том, что, как я заметил, если у нас ещё не набралось данных на несколько страниц, страница только одна и ссылка на следующую не будет выведена с самого начала, скрипт некорректно обрабатывает такую ситуацию. Поэтому я просто не инициализирую его в таком случае. Вот и всё ? И, как говорится, совсем малой кровью - всё сделано за нас.

Комментарии