[битрикс] Создание кнопки 'загрузить ещё'

Легкий способ сделать в битриксе функционал подгрузки новостей ввиде кнопки "загрузить ещё".

  1. Создадим шаблон компонента постраничной навигации (bitrix:system.pagenavigation).
  2. Адаптируем шаблон компонента списка новостей (bitrix:news.list).
  3. Разместим на странице и настроим компонент (bitrix:news.list).

Создание шаблона постраничной навигации

В данном примере создадим шаблон вручную, но вы можете просто скопировать один из стандартных шаблонов и заменить в нем код на мой.

Для начала создадим раздел system.pagenavigation в шаблоне сайта:

/bitrix/templates/[ваш шаблон]/components/bitrix/

или

/local/templates/[ваш шаблон]/components/bitrix/

В нем создадим подраздел с названием нашего шаблона. Назовем его show-more.

Каждый шаблон компонента должен содержать файл template.php, в нем будет храниться оформление.

Первым делом возьмемся за template:

template.php
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
$this->createFrame()->begin("Загрузка навигации");
?>

<?if($arResult["NavPageCount"] > 1):?>
    <?if ($arResult["NavPageNomer"]+1 <= $arResult["nEndPage"]):?>
        <?
            $plus = $arResult["NavPageNomer"]+1;
            $url = $arResult["sUrlPathParams"] . "PAGEN_".$arResult["NavNum"]."=".$plus;
        ?>
        <div class="row mt-5 js-show_more--show-more">
            <div class="col-12 text-center">
                <button class="btn btn-outline-dark rounded-pill fw-base px-4 py-2 js-show_more--show-more__btn" data-url="<?=$url?>">Загрузить еще</button>
                <div class="fw-light text-center mt-4">Отображается <?=$arResult["NavLastRecordShow"]?> из <?=$arResult["NavRecordCount"]?></div>
            </div>
        </div>
    <?else:?>
    <?endif?>
<?endif?>

Теперь самое главное - скрипт, рядом с template.php создаём файл script.js:

script.js
function initShowMore() {
    const showMoreBtn = document.querySelector(".js-show_more--show-more__btn");
    const showMoreWrapper = document.querySelector(".js-show_more--show-more");
    const pageItemsList = document.querySelector(".js-show_more--items");
    const pageItemsUrl = showMoreBtn.dataset.url;

    if(!showMoreWrapper || !pageItemsUrl) return;

    showMoreBtn.addEventListener("click", function (e) {
        e.preventDefault();
        showMoreBtn.disabled = true;

        fetch(pageItemsUrl).then(function (response) {
            return response.text();
        }).then(function (html) {
            const parser = new DOMParser();
            const pageItemsDOM = parser.parseFromString(html, 'text/html');
            const pageItemshowMore = pageItemsDOM.querySelector(".js-show_more--show-more");

            pageItemsDOM.querySelectorAll(".js-show_more--items .js-show_more--item").forEach(item => pageItemsList.appendChild(item));

            if(pageItemshowMore) {
                showMoreWrapper.innerHTML = pageItemshowMore.innerHTML;
                initShowMore();
            } else {
                showMoreWrapper.remove();
            }
        }).catch(function (err) {
            console.warn('Ошибка при загрузки элементов.', err);
        });
    })
}

initShowMore();

Шаблон компонента списка новостей

Создадим папку шаблона компонента:

/local/templates/[ваш шаблон]/components/bitrix/news.list/show_more_news/

либо

/bitrix/templates/[ваш шаблон]/components/bitrix/news.list/show_more_news/

Шаблон будет состоять всего из одного файла template.php:

template.php
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
$this->setFrameMode(true);
?>
<div class="js-show_more--items">
    <?foreach($arResult["ITEMS"] as $arItem):?>
        <?
            $this->AddEditAction($arItem['ID'], $arItem['EDIT_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_EDIT"));
            $this->AddDeleteAction($arItem['ID'], $arItem['DELETE_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_DELETE"), array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM')));
        ?>
        <div id="<?=$this->GetEditAreaId($arItem['ID']);?>" class="js-show_more--item">

            <a href="<?=$arItem["DETAIL_PAGE_URL"]?>">
                    <h2><?=$arItem["NAME"]?></h2>
            </a>

            <?=CFile::ShowImage($arItem['PREVIEW_PICTURE'])?>

            <?=$arItem['PREVIEW_TEXT']?>
        </div>
    <?endforeach;?>
</div>

<?=$arResult['NAV_STRING']?>

Оформление может использоваться какое угодно. Важная деталь: все элементы должны быть обёрнуты в блок с классом js-show_more--items, а каждый элемент иметь класс js-show_more--item (как в скрипте из второго пункта).

Размещение на странице и настройка компонента

На нужной странице размещаем компонент bitrix:news.list и настраиваем на необходимый инфоблок.

В качестве шаблона постраничной навигации - show-more.

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