javascript - 在多条件下拉过滤器中,如何显示结果内容?
问题描述
我已经建立了一个过滤器,它允许我根据第一个菜单中选择的选项来缩小标准。选择第二个选项后,我将无法根据该标准显示内容。
我错过了什么?
var articles = document.getElementsByClassName("article");
var years = {
news: [2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2012],
analysis: [2020, 2019, 2018, 2017, 2016],
press: [
2021,
2020,
2019,
2018,
2017,
2016,
2015,
2014,
2013,
2012,
2011,
2010,
2009,
2008,
2007,
2006
]
};
//change values in second menu based on first selection
function changeType(value) {
if (value.length == 0)
document.getElementById("selectYear").innerHTML = "<option></option>";
else {
var catOptions = "";
for (yearId in years[value]) {
catOptions += "<option>" + years[value][yearId] + "</option>";
}
document.getElementById("selectYear").innerHTML = catOptions;
}
// if (value !== '') {
// console.log(value);
// } else {
// console.log('nothing happened');
// }
}
//display results from filter
var storyTypeSelect = document.getElementById("selectStoryType");
var yearSelect = document.getElementById("selectYear");
function getStory() {
display(storyTypeSelect.value, yearSelect.value);
}
function getYear() {
display(storyTypeSelect.value, yearSelect.value);
}
function display(getStory, getYear) {
Array.from(articles).forEach((article) => article.classList.remove('hidden'));
if (getStory) {
Array.from(articles)
.filter((article) => !article.classList.contains(getStory))
.forEach((article) => article.classList.add('hidden'));
}
if (getYear) {
Array.from(articles)
.filter((article) => !article.classList.contains(getYear))
.forEach((article) => article.classList.add('hidden'));
}
}
/* filters */
.content {
margin: 0 10px;
}
.filter span {
color: var(--grey-4);
text-transform: uppercase;
font-size: 12px;
line-height: 12px;
letter-spacing: 1px;
padding: 0 0 10px 3px;
border-bottom: 1px solid var(--grey-6);
display: flex;
align-items: center;
}
.filter select.filter__type,
.clear span {
color: var(--secondary-color);
font-size: 12px;
line-height: 12px;
letter-spacing: 1px;
text-transform: uppercase;
font-weight: var(--fw-bold);
border: none;
}
.filter select.filter__type option {
background: var(--secondary-color);
color: var(--grey-6);
margin: 0.5em 0;
}
.hidden {
display: none;
}
section {
margin: 5em 0;
}
@media screen and (min-width: 320px) {
section.filter {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 10vh;
margin: 4em 0;
}
.clear span {
display: block;
align-items: center;
width: 100%;
padding: 0 3px;
}
.filter select.filter__type,
.clear span {
padding: 10px 0;
border-bottom: 1px solid var(--grey-6);
}
}
<section class="filter">
<span>filter by</span>
<select name="storyType" class="filter__type" id="storyType" onChange="changeType(this.value);">
<option value="" selected disabled="disabled">Story Type</option>
<option value="news">News and Media</option>
<option value="analysis">Analysis</option>
<option value="press">Press Releases</option>
</select>
<select name="year" class="filter__type" id="year">
<option value="" disabled selected>Year</option>
</select>
<div class="clear">
<span>clear filters</span>
</div>
</section>
<section class="results">
<h2>Results</h2>
<div class="results__content hidden">
<div class="article news 2017">A news article from 2017.</div>
<div class="article analysis 2019">An analysis article from 2019.</div>
<div class="article press 2008">A press release from 2008.</div>
</div>
</section>
解决方案
您的代码有点混乱,没有通过基于类别填充年份的第一阶段。所以我从伸展写了它:
const select = document.querySelector("#year")
// fetch year selector
let selectedCategory
let selectedYear
// declare two variables for later search
function changeType(value) {
console.clear()
console.log(value)
select.options.length = 0
// empty the year select on every change
select.innerHTML = '<option value="" disabled selected>Year</option>'
// put first option in
selectedCategory = value
// save selected category for later search
years[value].forEach(e => {
console.log(e)
// for each year in objects property by selected category
const option = document.createElement('option');
option.text = e;
select.insertAdjacentElement("beforeend", option)
// create and insert options as years
})
[...document.querySelectorAll(".article")].forEach(article => article.classList.add("hidden")) // reset articles
}
function changeYear(value) {
console.log(value)
selectedYear = value;
// on year change save selected Year variable
[...document.querySelectorAll("." + selectedCategory)].forEach(el => {
// use category to select all divs that have class of your category
console.log(el)
el.classList.contains(selectedYear) ? el.classList.remove("hidden") : el.classList.add("hidden")
// then check if divs have selected year, if not hide.
})
}
使用上面的代码进行测试,因为它将控制台记录每个步骤
我还将hidden
类从父 div 移动到每个内部,因为更容易在它们上切换该类以进行隐藏/显示。
工作小提琴:
var articles = document.getElementsByClassName("article");
var years = {
news: [2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2012],
analysis: [2020, 2019, 2018, 2017, 2016],
press: [2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012, 2011, 2010, 2009, 2008, 2007, 2006]
};
const select = document.querySelector("#year")
let selectedCategory, selectedYear
function changeType(value) {
select.options.length = 0
select.innerHTML = '<option value="" disabled selected>Year</option>'
selectedCategory = value
years[value].forEach(e => {
const option = document.createElement('option');
option.text = e;
select.insertAdjacentElement("beforeend", option)
});
[...document.querySelectorAll(".article")].forEach(article => article.classList.add("hidden")) // reset articles
}
function changeYear(value) {
selectedYear = value;
[...document.querySelectorAll("." + selectedCategory)].forEach(el => {
el.classList.contains(selectedYear) ? el.classList.remove("hidden") : el.classList.add("hidden")
})
}
/* filters */
.content {
margin: 0 10px;
}
.filter span {
color: var(--grey-4);
text-transform: uppercase;
font-size: 12px;
line-height: 12px;
letter-spacing: 1px;
padding: 0 0 10px 3px;
border-bottom: 1px solid var(--grey-6);
display: flex;
align-items: center;
}
.filter select.filter__type,
.clear span {
color: var(--secondary-color);
font-size: 12px;
line-height: 12px;
letter-spacing: 1px;
text-transform: uppercase;
font-weight: var(--fw-bold);
border: none;
}
.filter select.filter__type option {
background: var(--secondary-color);
color: var(--grey-6);
margin: 0.5em 0;
}
.hidden {
display: none;
}
section {
margin: 5em 0;
}
@media screen and (min-width: 320px) {
section.filter {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 10vh;
margin: 4em 0;
}
.clear span {
display: block;
align-items: center;
width: 100%;
padding: 0 3px;
}
.filter select.filter__type,
.clear span {
padding: 10px 0;
border-bottom: 1px solid var(--grey-6);
}
}
<section class="filter">
<span>filter by</span>
<select name="storyType" class="filter__type" id="storyType" onChange="changeType(this.value);">
<option value="" selected disabled="disabled">Story Type</option>
<option value="news">News and Media</option>
<option value="analysis">Analysis</option>
<option value="press">Press Releases</option>
</select>
<select name="year" class="filter__type" id="year" onChange="changeYear(this.value);">
<option value="" disabled selected>Year</option>
</select>
<div class="clear">
<span>clear filters</span>
</div>
</section>
<section class="results">
<h2>Results</h2>
<div class="results__content">
<div class="article news 2017 hidden">A news article from 2017.</div>
<div class="article analysis 2019 hidden">An analysis article from 2019.</div>
<div class="article press 2008 hidden">A press release from 2008.</div>
</div>
</section>
推荐阅读
- powerbi - 在 Power BI 中加载了一个 excel 文件,但在处理关系时显示为空(每一列)
- google-sheets-formula - 如何在没有宏的情况下显示行位置变化
- r - 如何检查 2 个向量是否相同,其中 NA 被视为正常值?
- reactjs - 映射一个反应组件不会返回到父组件
- javascript - 如果没有组返回结果,如何构建不返回空字符串的正则表达式
- c# - 更改嵌套在 CollectionView 中的标签
- xml - 我还需要这个 manifest.vista 文件吗?
- c# - 如何使用 iTextsharp 将 PDF 转换为图像?
- stata - 计算面板数据集中分类变量的变化次数
- regex - 是否可以根据其内容找到一个组但有替代方案?