Добавить loader (лоадер) в умный фильтр. Битрикс catalog.smart.filter

global.js

Наверняка loader нам понадобиться не только в фильтре, поэтому имеет смысл вынести код в общий файл и обращаться к нему с любых мест проекта.

/**
 * Loader на блок.
 *
 * action: add/remove
 */
function toggleLoader(element, action='add') {
    if(!element) {
        return false;
    }

    if (action === 'add') {
        element.classList.add('_loader');
    }

    if (action === 'remove') {
        element.classList.remove('_loader');
    }
}

/**
 * Loader на кнопку.
 *
 * action: add/remove
 */
function toggleLoaderButton(button, action='add') {
    if (action === 'add') {
        button.querySelector('.loader').classList.add('active')
    }
    if (action === 'remove') {
        button.querySelector('.loader').classList.remove('active')
    }
}

script.js

catalog.smart.filter/template/script.js

Нам нужно чтобы loader отображался до того как компонент фильтра отправляет запрос серверу и скрывался после получения ответа.

Для этого добавим включение в метод click()

function JCSmartFilter(ajaxURL, viewMode, params)
{
    // ...

    // Custom
    this.nodeFilter = document.querySelector('[data-filter="catalog"]') ?? null;
}

JCSmartFilter.prototype.click = function(checkbox)
{
    if (this.nodeFilter) {
        toggleLoader(this.nodeFilter)
    }

    // ...
};

И выключим его в postHandler()

JCSmartFilter.prototype.postHandler = function (result, fromCache)
{
    //...

    if (this.nodeFilter) {
        toggleLoader(this.nodeFilter, 'remove')
    }
};

CSS

/*=== Loader ===*/
._loader {
    position: relative;
}

._loader:before {
    content: '';
    background: rgba(255, 255, 255, .8);
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
}

._loader:after {
    content: '';
    width: 48px;
    height: 48px;
    border: 5px solid var(--gray-20);
    border-bottom-color: var(--green);
    border-radius: 50%;
    display: inline-block;
    box-sizing: border-box;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 20;
    animation: rotation 1s linear infinite;
}

@keyframes rotation {
    0% {
        transform: translate(-50%, -50%) rotate(0deg);
    }
    100% {
        transform: translate(-50%, -50%) rotate(360deg);
    }
}