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);
}
}