Бесконечный скролл в Bitrix, кастомизируем компонент `news.list`

Необходимость в короткие сроки реализовать т.н. `infinite scroll` (или попросту бесконечный скролл) на сайте под Bitrix, родила кастомизированный компонент `bitrix:news.list`.

Мы знаем, что компонент `news.list` использует свою постраничку, которую можно использовать в режиме `AJAX` (‘AJAX_MODE’ => ‘Y’), что позволяет обновлять новости в компоненте, не перезагружая страницы.

 

Как это работает?

Когда обработчик компонентов встречает на своем пути компонент с таким параметром, то создается экземпляр служебного класса CComponentAjax. Этот экземпляр вычисляет для компонента уникальный идентификатор сессии на основе результата функции debug_backtrace() (что поднимает планку требуемой версии PHP до 5.0.0). Далее, перехватывается вывод компонента и следующим образом обрабатывается:

  1. Прежде всего, все ссылки, встреченные внутри компонента, преобразуются в AJAX-вызовы. То есть, если в выводе встречается строка вида

<a href=»my.php?ID=123&action=display»>Просмотреть</a>

она заменяется на следующую:

<a href=»my.php?ID=123&action=display» onclick=»jsAjaxUtil.InsertDataToNode(‘my.php?ID=123&action=display&bxajaxid=1ecd88a66ec8f6aca9f700e8f0e7ef13’, ‘comp_1ecd88a66ec8f6aca9f700e8f0e7ef13’, true); return false;»>Просмотреть</a>

Мы имеем ту же самую ссылку, что и была, только с некоторыми «вкраплениями». Строка 1ecd88a66ec8f6aca9f700e8f0e7ef13 – это и есть тот самый уникальный идентификатор сессии; comp_1ecd88a66ec8f6aca9f700e8f0e7ef13 – это идентификатор контейнера, в который заключается вывод компонента, и куда мы будем вставлять результат AJAX-запроса.

 

Итак, принцип работы компонента в режиме AJAX мы уже представляем, дело за малым — написать код, который будет вытаскивать новости при достижении окончания страницы (естесственно, на js c использованием jQuery).


$(function()
{

$(window).scroll(function(){
height = getDocumentHeight(); //обратите внимание, для определения высоты страницы используем отдельную функцию, т.к. стандартные средства некроссбраузерны

if (window.pageYOffset == height - $(window).height())
{
if (parent.length>0)
{
upd();
}
}
});
var ua = navigator.userAgent.toLowerCase();
var isOpera = (ua.indexOf('opera') > -1);
var isIE = (!isOpera &amp;amp;amp;&amp;amp;amp; ua.indexOf('msie') > -1);

function getDocumentHeight() {
return Math.max(document.compatMode != 'CSS1Compat' ? document.body.scrollHeight : document.documentElement.scrollHeight, getViewportHeight());
}

function getViewportHeight() {
return ((document.compatMode || isIE) &amp;amp;amp;&amp;amp;amp; !isOpera) ? (document.compatMode == 'CSS1Compat') ? document.documentElement.clientHeight : document.body.clientHeight : (document.parentWindow || document.defaultView).innerHeight;
}
});

function upd()

{
var next_page = curr_page*1 +1;
$.get('/posts/'+rubr+'/?SECTION_CODE='+rubr+'&amp;amp;amp;PAGEN_2='+next_page+'&amp;amp;amp;bxajaxid='+parent_id, function(data) { parent.append(data); });

curr_page++;

}

 

Функция upd(), как вы уже поняли, подтягивает новости со следующей страницы при достижении конца текущей и добавляет их в общий список.

 

  • Александр

    Добрый день)

    добавил ваш скрипт в файл script.js который находится в папке \bitrix\templates\название шаблона сайта\components\bitrix\news.list\pesko — почему-то при достижени низа страницы ничего не подгружается.

    настройки компонента:
    IncludeComponent(
    «bitrix:news.list»,
    «pesko»,
    Array(
    «DISPLAY_DATE» => «Y»,
    «DISPLAY_NAME» => «Y»,
    «DISPLAY_PICTURE» => «Y»,
    «DISPLAY_PREVIEW_TEXT» => «Y»,
    «AJAX_MODE» => «Y»,
    «IBLOCK_TYPE» => «glass»,
    «IBLOCK_ID» => «36»,
    «NEWS_COUNT» => «12»,
    «SORT_BY1» => «ACTIVE_FROM»,
    «SORT_ORDER1» => «DESC»,
    «SORT_BY2» => «SORT»,
    «SORT_ORDER2» => «ASC»,
    «FILTER_NAME» => «arrFilter»,
    «FIELD_CODE» => array(),
    «PROPERTY_CODE» => array(«ALT», «CATEGORY», «PHOTO»),
    «CHECK_DATES» => «Y»,
    «DETAIL_URL» => «»,
    «PREVIEW_TRUNCATE_LEN» => «»,
    «ACTIVE_DATE_FORMAT» => «d.m.Y»,
    «SET_TITLE» => «N»,
    «SET_STATUS_404» => «N»,
    «INCLUDE_IBLOCK_INTO_CHAIN» => «Y»,
    «ADD_SECTIONS_CHAIN» => «Y»,
    «HIDE_LINK_WHEN_NO_DETAIL» => «N»,
    «PARENT_SECTION» => «»,
    «PARENT_SECTION_CODE» => «»,
    «CACHE_TYPE» => «N»,
    «CACHE_TIME» => «36000000»,
    «CACHE_FILTER» => «N»,
    «CACHE_GROUPS» => «Y»,
    «DISPLAY_TOP_PAGER» => «N»,
    «DISPLAY_BOTTOM_PAGER» => «Y»,
    «PAGER_TITLE» => «»,
    «PAGER_SHOW_ALWAYS» => «Y»,
    «PAGER_TEMPLATE» => «.default»,
    «PAGER_DESC_NUMBERING» => «N»,
    «PAGER_DESC_NUMBERING_CACHE_TIME» => «36000»,
    «PAGER_SHOW_ALL» => «Y»,
    «AJAX_OPTION_JUMP» => «Y»,
    «AJAX_OPTION_STYLE» => «Y»,
    «AJAX_OPTION_HISTORY» => «N»
    )
    );?>

    Подскажите пожалуйста в чем может быть проблема, или я что-то не так сделал.
    За ранее спасибо)

  • О,Иван

    О, Денисова!