代码之家  ›  专栏  ›  技术社区  ›  Millhorn

如何在vanilla JS中创建空状态的结果?

  •  -1
  • Millhorn  · 技术社区  · 5 年前

    这看起来像一个大脚本,但过滤器的功能并没有那么大。为空状态创建结果时遇到问题。

    即。;如果过滤器选择与任何对象不匹配,则显示

    chosenItems.length == 0 ,然后显示一条消息。。。但我在这里遗漏了一些东西。

    //dropdown
    let current_story = "",
      current_year = "";
    
    for (const dropdown of document.querySelectorAll(".custom__select-wrapper:not(.clearFilter)")) {
      dropdown.addEventListener("click", function () {
        this.querySelector(".custom__select").classList.toggle("open");
      });
    }
    
    for (const option of document.querySelectorAll(".custom__option")) {
      option.addEventListener("click", function () {
        if (!this.classList.contains("selected")) {
          this.parentNode
            .querySelector(".custom__option.selected")
            .classList.remove("selected");
          this.classList.add("selected");
          this.closest(".custom__select").querySelector(
            ".custom__select-trigger h6"
          ).textContent = this.textContent;
          if (this.getAttribute("data-year")) {
            current_year = this.dataset["year"];
            yearFilter(this.dataset["year"]);
          } else {
            current_story = this.dataset["type"];
            storyFilter(this.dataset["type"]);
          }
        }
      });
    }
    
    window.addEventListener("click", function (e) {
      for (const select of document.querySelectorAll(".custom__select")) {
        if (!select.contains(e.target)) {
          select.classList.remove("open");
        }
      }
    });
    
    // filter
    function storyFilter(className) {
      const list = document.querySelectorAll(".article");
    
      for (const article of list) {
        article.classList.add("hidden");
        article.classList.remove("chosen");
        if (className == "all") {
          if (
            current_year !== "" &&
            current_year == "all"
          ) {
            article.classList.add("chosen");
          } else if (
            current_year !== "" &&
            article.getAttribute("data-year") === current_year
          ) {
            article.classList.add("chosen");
          } else if (current_year === "") {
            article.classList.add("chosen");
          }
        } else if (article.getAttribute("data-type") === className) {
          if (
            current_year !== "" &&
            current_year == "all"
          ) {
            article.classList.add("chosen");
          } else if (
            current_year !== "" &&
            article.getAttribute("data-year") === current_year
          ) {
            article.classList.add("chosen");
          } else if (current_year === "") {
            article.classList.add("chosen");
          }
        }
      }
      loadInitial();
      checkLoadMore()
    }
    
    function yearFilter(className) {
      const list = document.querySelectorAll(".article");
    
      for (const article of list) {
        article.classList.add("hidden");
        article.classList.remove("chosen");
        if (className == "all") {
          if (
            current_story !== "" &&
            current_story == "all"
          ) {
            article.classList.add("chosen");
          } else if (
            current_story !== "" &&
            article.getAttribute("data-type") === current_story
          ) {
            article.classList.add("chosen");
          } else if (current_story === "") {
            article.classList.add("chosen");
          }
        } else if (article.getAttribute("data-year") == className) {
          if (
            current_story !== "" &&
            current_story == "all"
          ) {
            article.classList.add("chosen");
          } else if (
            current_story !== "" &&
            article.getAttribute("data-type") === current_story
          ) {
            article.classList.add("chosen");
          } else if (current_story === "") {
            article.classList.add("chosen");
          }
        }
      }
      loadInitial();
      checkLoadMore()
    }
    
    
    //global load more functionality
    const loadmore = document.getElementById("loadMore");
    const hiddenItems = [...document.querySelectorAll(".article.hidden")];
    // const chosenItems = [...document.querySelectorAll(".article.hidden.chosen")];
    
    // console.log(hiddenItems);
    
    hiddenItems.splice(0, 9).forEach(
      elem => elem.classList.remove("hidden")
    );
    
    loadmore.addEventListener('click', function (e) {
      e.preventDefault();
      let chosenItems = [...document.querySelectorAll('.article.hidden.chosen')];
    
      console.log(chosenItems.length);
    
      chosenItems.splice(0, 6).forEach(
        elem => elem.classList.remove("hidden")
      )
    
      if (chosenItems.length <= 6) {
        loadmore.classList.add("hidden");
      }
    });
    
    function loadInitial() {
      let chosen = [...document.querySelectorAll(".chosen")];
    
      chosen.splice(0, 9).forEach(
        elem => elem.classList.remove("hidden")
      );
    }
    
    function checkLoadMore() {
      let chosen = [...document.querySelectorAll(".chosen")];
    
      if (chosen.length <= 6) {
        loadmore.classList.add("hidden");
      } else if (loadmore.classList.contains("hidden")) {
        loadmore.classList.remove("hidden");
      }
    }
    
    //reset button
    let filterSelection = document.querySelectorAll(".dropdown").forEach(dropdown => {
      dropdown.addEventListener("click", function () {
        selectedFilter.classList.remove("hidden");
      })
    });
    
    function clearSelection() {
      document.querySelector(".custom__select-wrapper .story-sel h6").textContent = "STORY TYPE";
      document.querySelector(".custom__select-wrapper .year-sel h6").textContent = "YEAR";
      document.querySelector(".custom__option.selected[data-type]").classList.remove("selected");
      document.querySelector(".custom__option.selected[data-year]").classList.remove("selected");
      document.querySelector(".custom__option[data-type='all']").classList.add("selected");
      document.querySelector(".custom__option[data-year='all']").classList.add("selected");
    
      selectedFilter.classList.add("hidden");
    
      let articles = [...document.querySelectorAll(".article")];
    
      current_story = "all";
      current_year = "all";
    
      articles.forEach(function (article) {
        article.classList.add("hidden");
        article.classList.add("chosen");
      });
      loadInitial();
      checkLoadMore();
    }
    
    if (document.querySelectorAll('.article.hidden.chosen').length < 1) {
      newsList.innerHTML = "<h1>Nothing</h1>";
    }
    @charset "UTF-8";
    .hidden {
      display: none;
    }
    
    .show {
      display: block;
    }
    
    button.clear {
      border: 0;
      background: #fff;
    }
    
    #selectedFilter {
      color: #005fec;
    }
    
    .nextcard {
      width: 250px;
      height: 150px;
      border: 2px solid black;
      border-radius: 4px;
    }
    
    @media screen and (min-width: 320px) {
      .filter__settings {
        display: flex;
        flex-direction: column;
      }
    
      .custom__select-wrapper h6 {
        padding: 0 3px;
        color: #a1b4c4;
        font-weight: 300;
      }
    
      .custom__select {
        position: relative;
        display: flex;
        flex-direction: column;
      }
    
      .custom__select-wrapper {
        position: relative;
        user-select: none;
        padding: 10px 0;
      }
    
      .custom__select-trigger {
        position: relative;
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 60px;
        cursor: pointer;
      }
    
      .custom__select-wrapper h6,
    .custom__select-trigger h6 {
        font-size: 12px;
        line-height: 12px;
        letter-spacing: 1px;
        text-transform: uppercase;
      }
    
      .custom__select-trigger h6 {
        color: #005fec;
        font-weight: 900;
      }
    
      .custom__select-wrapper #selectedFilter {
        font-size: 12px;
        line-height: 12px;
        letter-spacing: 1px;
        text-transform: uppercase;
        color: #005fec;
        font-weight: 800;
        padding: 0;
      }
    
      .custom__options {
        position: absolute;
        display: block;
        background-color: #005fec;
        top: 100%;
        left: 0;
        right: 0;
        border-top: 0;
        transition: all 0.5s;
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        z-index: 2;
      }
      .custom__options:before, .custom__options:after {
        content: "";
        position: absolute;
        bottom: 100%;
        left: 11px;
        border: 11px solid transparent;
        border-bottom-color: #005fec;
      }
    
      .custom__select-trigger,
    .custom__option {
        letter-spacing: 1px;
        font-weight: 800;
        color: #005fec;
        border: 0;
        background: transparent;
      }
    
      .custom__select.open .custom__options {
        opacity: 1;
        visibility: visible;
        pointer-events: all;
        color: #fff;
        width: 100%;
      }
    
      .custom__option {
        position: relative;
        display: block;
        padding: 0 22px 0 20px;
        font-weight: 300;
        color: #fff;
        cursor: pointer;
        transition: all 0.5s;
        font-size: 12px;
        line-height: 12px;
        margin: 1.5em 0;
      }
      .custom__option:hover {
        cursor: pointer;
      }
      .custom__option.selected {
        color: #ffffff;
      }
      .custom__option.selected::before {
        content: "•";
        margin-left: -12px;
        padding-right: 8px;
      }
    
      /* arrow */
      .arrow {
        position: relative;
        height: 10px;
        width: 10px;
        margin-left: 2em;
      }
      .arrow::before, .arrow::after {
        content: "";
        position: absolute;
        bottom: 0px;
        width: 0.1rem;
        height: 100%;
        transition: all 0.5s;
      }
      .arrow::before {
        left: -2px;
        transform: rotate(45deg);
        background-color: #394a6d;
      }
      .arrow::after {
        left: 2px;
        transform: rotate(-45deg);
        background-color: #394a6d;
      }
    
      .open .arrow::before {
        left: -2px;
        transform: rotate(-45deg);
      }
      .open .arrow::after {
        left: 2px;
        transform: rotate(45deg);
      }
    
      .arrow::after {
        left: 5px;
        transform: rotate(-45deg);
        background-color: #394a6d;
      }
    
      .open .arrow::before {
        left: -2px;
        transform: rotate(-45deg);
      }
      .open .arrow::after {
        left: 5px;
        transform: rotate(45deg);
      }
    }
    @media screen and (min-width: 768px) {
      .filter__settings {
        flex-direction: row;
      }
    
      .custom__select-trigger {
        justify-content: space-evenly;
        margin-right: auto;
      }
    
      .filter__settings .custom__select-wrapper {
        margin: 0 2em;
      }
    
      .custom__select-wrapper {
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .custom__select-wrapper:last-child {
        margin-left: auto;
      }
    }
    <div class="container" id="listArticles">
      <section class="filter">
        <div class="filter__settings">
          <div class="custom__select-wrapper">
            <h6>filter by</h6>
          </div>
          <div class="custom__select-wrapper">
            <div class="custom__select story-sel selector">
              <div class="custom__select-trigger">
                <h6>Story Type</h6>
                <div class="arrow"></div>
              </div>
              <div class="custom__options dropdown story-selector" id="storyFilter">
                <span class="custom__option selected" data-type="all">All</span>
                <span class="custom__option" data-type="news">News and Media</span>
                <span class="custom__option" data-type="analysis">Analysis</span>
                <span class="custom__option" data-type="press">Press Releases</span>
              </div>
            </div>
          </div>
          <div class="custom__select-wrapper">
            <div class="custom__select year-sel selector">
              <div class="custom__select-trigger">
                <h6>Year</h6>
                <div class="arrow"></div>
              </div>
              <div class="custom__options dropdown year-selector" id="yearFilter">
                <span class="custom__option selected" data-year="all">All</span>
                <span class="custom__option" data-year="2021">2021</span>
                <span class="custom__option" data-year="2020">2020</span>
                <span class="custom__option" data-year="2019">2019</span>
                <span class="custom__option" data-year="2018">2018</span>
                <span class="custom__option" data-year="2017">2017</span>
                <span class="custom__option" data-year="2016">2016</span>
                <span class="custom__option" data-year="2015">2015</span>
                <span class="custom__option" data-year="2014">2014</span>
                <span class="custom__option" data-year="2013">2013</span>
                <span class="custom__option" data-year="2012">2012</span>
                <span class="custom__option" data-year="2011">2011</span>
                <span class="custom__option" data-year="2010">2010</span>
                <span class="custom__option" data-year="2009">2009</span>
                <span class="custom__option" data-year="2008">2008</span>
                <span class="custom__option" data-year="2007">2007</span>
                <span class="custom__option" data-year="2006">2006</span>
              </div>
            </div>
          </div>
          <div class="custom__select-wrapper clearFilter">
            <h6 class="clear hidden" id="selectedFilter" onclick="clearSelection()">clear filters</h6>
          </div>
        </div>
      </section>
    
      <div class="row" id="newsList">
        <div class="col-sm-12 col-md-6 col-lg-4 d-flex align-items-stretch article chosen news" data-year="2021" data-type="news">
          <div class="nextcard">
            <div class="nextcard__content">
              <div class="nextcard__date">
                February 4, 2021
              </div>
              <div class="nextcard__title">
                <h4>Red Fish</h4>
              </div>
              <div class="nextcard__footer">
                <a href="#" title="Customer Experience is the New Flagship Store" class="stretched-link nextcard__icon" rel="noopener nofollow" role="link" tabindex="0" aria-hidden="true"></a>
              </div>
            </div>
          </div>
        </div>
        <div class="col-sm-12 col-md-6 col-lg-4 d-flex align-items-stretch article chosen news" data-year="2021" data-type="news">
          <div class="nextcard">
            <div class="nextcard__content">
              <div class="nextcard__date">
                February 4, 2020
              </div>
              <div class="nextcard__title">
                <h4>Blue Fish</h4>
              </div>
              <div class="nextcard__footer">
                <a href="#" title="Customer Experience is the New Flagship Store" class="stretched-link nextcard__icon" rel="noopener nofollow" role="link" tabindex="0" aria-hidden="true"></a>
              </div>
            </div>
          </div>
        </div>
        <div class="col-sm-12 col-md-6 col-lg-4 d-flex align-items-stretch article chosen news" data-year="2021" data-type="press">
          <div class="nextcard">
            <div class="nextcard__content">
              <div class="nextcard__date">
                February 4, 2019
              </div>
              <div class="nextcard__title">
                <h4>Red Fish</h4>
              </div>
              <div class="nextcard__footer">
                <a href="#" title="Customer Experience is the New Flagship Store" class="stretched-link nextcard__icon" rel="noopener nofollow" role="link" tabindex="0" aria-hidden="true"></a>
              </div>
            </div>
          </div>
        </div> 
        <div class="col-sm-12 col-md-6 col-lg-4 d-flex align-items-stretch article chosen news" data-year="2021" data-type="analysis">
          <div class="nextcard">
            <div class="nextcard__content">
              <div class="nextcard__date">
                February 4, 2018
              </div>
              <div class="nextcard__title">
                <h4>Blue Fish</h4>
              </div>
              <div class="nextcard__footer">
                <a href="#" title="Customer Experience is the New Flagship Store" class="stretched-link nextcard__icon" rel="noopener nofollow" role="link" tabindex="0" aria-hidden="true"></a>
              </div>
            </div>
          </div>
        </div>    
      </div>
    </div>
    0 回复  |  直到 5 年前
        1
  •  0
  •   Alex Mckay    5 年前

    在这里,您似乎正在为自己创建大量不必要的工作,并且考虑到脚本中存在的大量变异,理解过滤过程是相当混乱的。您可以尝试使用非变异列表方法简化脚本。

    const list = [16, 17, 18, 19, 20]
    const isAdult = x => x >= 18
    const isEven = x => x % 2 === 0
    const results = list.filter(isAdult).filter(isEven) // [18, 20]
    
    // Evaluates to true if length > 0, false otherwise
    if (results.length) {
      // Display results
    } else {
      const el = document.getElementById('results')
      el.innerText = 'Results Not Found'
    }