首页 > 解决方案 > 在多条件下拉过滤器中,如何显示结果内容?

问题描述

我已经建立了一个过滤器,它允许我根据第一个菜单中选择的选项来缩小标准。选择第二个选项后,我将无法根据该标准显示内容。

我错过了什么?

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>

标签: javascripthtml

解决方案


您的代码有点混乱,没有通过基于类别填充年份的第一阶段。所以我从伸展写了它:

    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>


推荐阅读