#javascript #html #jquery #json #filter
#javascript #HTML #jquery #json #Фильтр
Вопрос:
У меня есть этот веб-сайт: https://www.australianathleticscalendar.com.au /
Я хочу сделать так, чтобы вы могли выбрать фильтр «События» и фильтр «Состояние» одновременно (т.Е. 100m и QLD одновременно), и пузырьки в каждом фильтре будут иметь стиль (например, как: фокус). С каждым фильтром выберите одну категорию. Когда вы меняете категории внутри фильтра, предыдущая выбранная также должна быть без стилей (т.е. Невозможно выбрать 100m и 200m одновременно. Переход от 100m к 200m приведет к удалению стиля из 100m и добавлению его к 200m).
Проблема с css заключается в том, что вы можете: фокусировать только один элемент за раз.
Как я могу добиться этого с помощью javascript?
Я поместил соответствующий код в codepen здесь .
Это функции, которые рисуют два фильтра:
function drawCategories() {
var template = Handlebars.compile(document.getElementById("menu-template").innerHTML);
console.log('draw ', this.products);
document.getElementById('menu-container').innerHTML = template(this.events);
}
function drawStates() {
var template = Handlebars.compile(document.getElementById("menu-template-2").innerHTML);
console.log('draw ', this.products);
document.getElementById('menu-container-states').innerHTML = template(this.states);
}
function showCategory(event) {
this.title = event;
drawProducts();
}
function showState(state) {
this.titleStates = state;
drawProducts();
}
И это HTML для двух фильтров:
<!-- Events filter -->
<div class="container">
<script id="menu-template" type="text/x-handlebars-template">
<ul class="navbar-nav">
{{#each this as |event|}}
<li class="nav-item"></li>
<a class="nav-link" href="#" onclick="showCategory('{{event.name}}');">{{event.name}}</a>
{{/each}}
<a class="navbar-brand hover-color" href="#" onclick="showAllEvents();">All Events</a>
</ul>
<ul class="navbar-nav ml-auto"></ul>
<li class="nav-item">
</li>
</ul>
</div>
</script>
</div>
<!-- States filter -->
<div class="container">
<script id="menu-template-2" type="text/x-handlebars-template">
<ul class="navbar-nav">
{{#each this as |state|}}
<li class="nav-item"></li>
<a class="nav-link nav-link-states" href="#" onclick="showState('{{state.name}}');">{{state.name}}</a>
{{/each}}
<a class="navbar-brand hover-color-states" href="#" onclick="showAllStates();">All States</a>
</ul>
<ul class="navbar-nav ml-auto"></ul>
<li class="nav-item">
</li>
</ul>
</div>
</script>
</div>
Комментарии:
1. Кстати, ваш HTML будет иметь повторяющиеся
id
значения атрибутов (напримерstateFilter
), что недопустимо в HTML. Вы должны удалить этиid
атрибуты. Похоже, они не служат какой-либо цели.2. существует
eventsFilter
иstateFilter
, который я добавил, когда пытался использоватьclassList
для :focus, но, похоже, я не могу найти дубликатstateFilter
3. Он становится дублирующимся, когда шаблон расширяется с помощью цикла handlebar
#each
. Ни один из HTML-файлов в таком цикле не должен иметьid
атрибутов.4. Кроме того, у вас больше закрытия
</li>
, чем открытия<li>
.5. Спасибо, я удалил эти идентификаторы и
</li>
.
Ответ №1:
Как часто бывает, есть много способов добиться этого. Я думаю, что проще всего было бы добавить дополнительный аргумент к вызовам, выполняемым в обработчиках щелчков — передача this
— чтобы обработчик точно знал, какой элемент DOM должен получить стиль:
<a onclick="showCategory(this, '{{event.name}}');">
<a onclick="showAllEvents(this);">
<a onclick="showState(this, '{{state.name}}');">
<a onclick="showAllStates(this);">
Затем в вашем коде определите функцию, которая будет применять класс CSS к данному элементу DOM, но также гарантирует, что это будет единственный элемент, имеющий этот класс. Затем используйте эту служебную функцию в обработчиках щелчков, которые теперь также должны принимать этот дополнительный аргумент:
// Utility function that ensures only one element has the given CSS class:
function selectElem(elem, className) {
let prevSelected = document.querySelector("." className);
if (prevSelected) prevSelected.classList.remove(className);
elem.classList.add(className);
}
function showCategory(elem, event) { // <-- extra parameter, here and below...
selectElem(elem, "selectedEvent"); // <-- add this call, here and below...
this.title = event;
drawProducts();
}
function showAllEvents(elem) {
selectElem(elem, "selectedEvent");
this.title = "All Events";
drawProducts();
}
function showState(elem, state) {
selectElem(elem, "selectedState"); // <-- different style here and below
this.titleStates = state;
drawProducts();
}
function showAllStates(elem) {
selectElem(elem, "selectedState");
this.titleStates = "All States";
drawProducts();
}
Теперь вам предстоит определить стиль двух новых классов CSS: selectedEvent и selectedState. Вы можете дать им одинаковое определение с помощью запятой:
.selectedState, .selectedEvent {
# Your styling ...
}