Isotope — это мощная библиотека для динамической фильтрации, сортировки и расположения элементов на веб-странице. Одной из ключевых задач при работе с интерактивными интерфейсами является сохранение текущего состояния фильтров и их восстановление при повторной загрузке страницы или переходе между вкладками. Это обеспечивает пользователю плавный и предсказуемый опыт взаимодействия с контентом.
Для хранения текущего фильтра удобно использовать
localStorage, который позволяет сохранять данные между
сессиями браузера. Пример подхода:
// Инициализация Isotope
var iso = new Isotope('.grid', {
itemSelector: '.grid-item',
layoutMode: 'fitRows'
});
// Функция применения фильтра
function applyFilter(filterValue) {
iso.arrange({ filter: filterValue });
// Сохраняем текущий фильтр
localStorage.setItem('currentFilter', filterValue);
}
// Восстановление фильтра при загрузке страницы
var savedFilter = localStorage.getItem('currentFilter');
if (savedFilter) {
applyFilter(savedFilter);
}
Ключевой момент: метод
arrange({ filter: ... }) не только применяет фильтр к
элементам, но и обеспечивает корректную анимацию расположения.
Когда требуется поддержка нескольких фильтров одновременно, например фильтр по категории и по тегу, можно хранить состояние в виде объекта JSON:
var filterState = {
category: '*',
tag: '*'
};
// Обновление фильтра
function updateFilter(type, value) {
filterState[type] = value;
var filterString = concatFilters(filterState);
iso.arrange({ filter: filterString });
localStorage.setItem('filterState', JSON.stringify(filterState));
}
// Конкатенация фильтров
function concatFilters(state) {
var filters = [];
if(state.category !== '*') filters.push('.' + state.category);
if(state.tag !== '*') filters.push('.' + state.tag);
return filters.length ? filters.join('') : '*';
}
// Восстановление при загрузке
var savedState = JSON.parse(localStorage.getItem('filterState'));
if(savedState) {
filterState = savedState;
iso.arrange({ filter: concatFilters(filterState) });
}
Выделение важного: правильное формирование строки
фильтров критично для корректного отображения. Isotope поддерживает
объединение классов через конкатенацию (например,
.category-tag), поэтому генерация строки должна учитывать
все активные фильтры.
Помимо фильтров, часто важно восстановить и сортировку:
// Сортировка элементов по атрибуту data-name
function sortItems(sortBy) {
iso.arrange({ sortBy: sortBy });
localStorage.setItem('sortBy', sortBy);
}
// Восстановление сортировки
var savedSort = localStorage.getItem('sortBy');
if(savedSort) {
iso.arrange({ sortBy: savedSort });
}
Isotope поддерживает несколько критериев сортировки одновременно,
используя объект sortAscending:
iso.arrange({
sortBy: ['name', 'price'],
sortAscending: { name: true, price: false }
});
Для сохранения такого сложного состояния также удобно использовать JSON.
Иногда требуется, чтобы состояние фильтров было доступно по ссылке. Для этого можно использовать URL-параметры:
function setFilterInURL(filterValue) {
var url = new URL(window.location);
url.searchParams.set('filter', filterValue);
window.history.replaceState({}, '', url);
}
function getFilterFromURL() {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get('filter') || '*';
}
var initialFilter = getFilterFromURL();
iso.arrange({ filter: initialFilter });
Преимущество этого подхода — возможность делиться ссылкой с конкретным состоянием фильтров.
Для кнопок фильтров удобно добавлять обработчик клика, который автоматически обновляет как Isotope, так и сохранённое состояние:
var filterButtons = document.querySelectorAll('.filter-button');
filterButtons.forEach(function(button) {
button.addEventListener('click', function() {
var filterValue = button.getAttribute('data-filter');
applyFilter(filterValue);
updateActiveButton(button);
});
});
function updateActiveButton(activeButton) {
filterButtons.forEach(btn => btn.classList.remove('is-active'));
activeButton.classList.add('is-active');
}
Важно: синхронизация состояния кнопок с сохранёнными фильтрами позволяет визуально отобразить активный фильтр после перезагрузки страницы.
Если элементы на странице добавляются динамически, Isotope требует
вызова метода appended или reloadItems перед
применением фильтров:
// Добавление новых элементов
var newElements = document.querySelectorAll('.grid .new-item');
iso.appended(newElements);
iso.arrange({ filter: concatFilters(filterState) });
Это гарантирует, что все новые элементы корректно попадут под текущие фильтры.
arrange().appended и reloadItems для интеграции новых
элементов с текущим состоянием.Хотите, я подготовлю отдельный подробный блок с примерами для комбинирования фильтров и сортировки вместе с динамическим сохранением состояния, который можно вставлять прямо в учебник? Это будет логическое продолжение этой главы.