надо сделать такой же функционал для фильтрации треков на странице,
как у
https://www.music-hub.ru/
все поля запроса хранятся в одном единственном параметре - filters
к примеру
https://www.music-hub.ru/?filters={%22genre%22:[%2...]}
Окей, с get запросами при нажатии чекбоксов я разобрался более менее
вот код
function restoreFilters() {
const params = new URLSearchParams(window.location.search);
const filtersParam = params.get('filters');
if (!filtersParam) return;
try {
const filters = JSON.parse(filtersParam);
if (filters.genre) {
filters.genre.forEach(function(val) {
const el = document.querySelector('input[name="genre"][value="' + val + '"]');
if (el) el.checked = true;
});
}
if (filters.mood) {
filters.mood.forEach(function(val) {
const el = document.querySelector('input[name="mood"][value="' + val + '"]');
if (el) el.checked = true;
});
}
if (filters.key) {
filters.key.forEach(function(val) {
const el = document.querySelector('input[name="key"][value="' + val + '"]');
if (el) el.checked = true;
});
}
if (filters.bpm) {
const bpmInput = document.getElementById('bpm');
const bpmDisplay = document.getElementById('bpm-value');
bpmInput.value = filters.bpm[0];
bpmDisplay.textContent = filters.bpm[0];
}
} catch (err) {
console.error("Ошибка при восстановлении фильтров:", err);
}
}
restoreFilters();
// Функция собирает выбранные значения фильтров и обновляет URL
function updateFilters() {
const newFilters = {};
// Сбор значений жанров
const genreInputs = document.querySelectorAll('input[name="genre"]');
const selectedGenres = [];
genreInputs.forEach(function (input) {
if (input.checked) selectedGenres.push(input.value);
});
if (selectedGenres.length > 0) newFilters.genre = selectedGenres;
// Сбор значений настроения
const moodInputs = document.querySelectorAll('input[name="mood"]');
const selectedMoods = [];
moodInputs.forEach(function (input) {
if (input.checked) selectedMoods.push(input.value);
});
if (selectedMoods.length > 0) newFilters.mood = selectedMoods;
// Сбор значений тональности
const keyInputs = document.querySelectorAll('input[name="key"]');
const selectedKeys = [];
keyInputs.forEach(function (input) {
if (input.checked) selectedKeys.push(input.value);
});
if (selectedKeys.length > 0) newFilters.key = selectedKeys;
// Сбор значения BPM – включаем только если оно изменено от значения по умолчанию
const bpmInput = document.getElementById('bpm');
const defaultBpm = bpmInput.getAttribute('data-default') || "200";
if (bpmInput.value && bpmInput.value !== defaultBpm) {
// Чтобы соответствовать примеру – значение оборачиваем в массив строк
newFilters.bpm = [bpmInput.value];
}
// Формирование нового URL: удаляем все прочие параметры и оставляем только filters
const currentUrl = new URL(window.location.href);
currentUrl.search = ""; // очищаем строку запроса
if (Object.keys(newFilters).length > 0) {
currentUrl.searchParams.set('filters', JSON.stringify(newFilters));
}
// Перенаправление происходит сразу после изменения любого фильтра
window.location.href = currentUrl.toString();
}
// Вешаем обработчик событий на все элементы фильтров (чекбоксы и ползунок BPM)
const filterElements = document.querySelectorAll('input[name="genre"], input[name="mood"], input[name="key"], input#bpm');
filterElements.forEach(function (el) {
el.addEventListener('change', updateFilters);
});
// Реальное обновление отображения значения BPM при движении ползунка
const bpmEl = document.getElementById('bpm');
const bpmDisplay = document.getElementById('bpm-value');
if (bpmEl && bpmDisplay) {
bpmEl.addEventListener('input', function() {
bpmDisplay.textContent = this.value;
});
}
});
Но как избежать кодирования скобок, что реализовано на сайте, который указан выше, я так и не понял.