【问题标题】:Filtering pizzas by ingredients按成分过滤比萨饼
【发布时间】:2019-10-16 18:18:07
【问题描述】:

我有一些按钮,您可以在其中选择要过滤的成分

//index.html

<div class="submenu">
    <input type="checkbox" class="filter-item" id="olive" onclick="filter()" />
    <label for="olive">
        <img alt="olive" src="img/png/pizza/olive.png" />
    </label>
    <input type="checkbox" class="filter-item" id="shrimp" onclick="filter()" />
    <label for="shrimp">
        <img alt="shrimp" src="img/png/pizza/shrimp.png" />
    </label>
    <input type="checkbox" class="filter-item" id="mushroom" onclick="filter()" />
    <label for="mushroom">
        <img alt="mushroom" src="img/png/pizza/champion.png" />
    </label>
    <input type="checkbox" class="filter-item" id="pepperoni" onclick="filter()" />
    <label for="pepperoni">
        <img alt="pepperoni" src="img/png/pizza/pepperoni.png" />
    </label>
    <footer id="filter-text">no filter applied</footer>
</div>

还有菜单项(比萨)

//index.html

<div class="menu-container">
    <img id="olive-pizza" class="menu-item olive" alt="olive" />
    <img id="pepperoni-pizza" class="menu-item pepperoni" alt="pepperoni" />
    <img id="shrimp pizza" class="menu-item shrimp" alt="shrimp" />
    <img class="menu-item mushroom" alt="mushroom" />
    <img class="menu-item olive pepperoni" alt="olive, pepperoni" />
    <img class="menu-item olive shrimp mushroom" alt="olive, shrimp, mushroom" />
</div>

我想显示包含所有所选成分的所有比萨饼。例如,如果选择橄榄和虾的成分,则仅显示至少同时具有这两个类别的比萨。

我的想法是将所有选定的成分放入数组itemsToFilter,然后将该数组中的每个项目与每个比萨饼的类别进行比较,然后显示“剩余”比萨饼。

函数如下:

var itemsToFilter = [];

//HTMLCollections, not arrays
ingredients = document.getElementsByClassName("filter-item"); 
pizzas = document.getElementsByClassName("menu-item");

function filter() {
    for (var i = 0; i < ingredients.length; i++) {
        if (ingredients[i].checked == true) {
            //add checked item to array itemsToFilter
            if (itemsToFilter.includes(ingredients[i].getAttribute("id")) == false) {
                itemsToFilter.push(ingredients[i].getAttribute("id"));
            }
        } else {
            //remove unchecked item from array itemsToFilter
            for (var y = itemsToFilter.length - 1; y >= 0; y--) {
                if (itemsToFilter[y] === ingredients[i].getAttribute("id")) {
                    if (itemsToFilter.includes(ingredients[i].getAttribute("id")) == true) {
                        itemsToFilter.splice(y, 1);
                    }
                }
            }
        }
        //show pizzas with classes that match items in array itemsToFilter
        for (var i = 0; i < pizzas.length; i++) {
            for (y in itemsToFilter) {
                if (pizzas[i].classList.contains(itemsToFilter[y]) == false) {
                    if (pizzas[i].classList.contains("show") == true) {
                        pizzas[i].classList.remove("show");
                    }
                    break;
                } else {
                    pizzas[i].classList.add("show");
                }
            }
        }
    }
}

这在某种程度上有效。它仅适用于第一个成分“橄榄”,它正确地添加了类节目,但是当未选中复选框时它不会删除类。其他成分甚至没有添加到数组 itemsToFilter 中。

有人有办法吗?

【问题讨论】:

    标签: javascript html for-loop filter htmlcollection


    【解决方案1】:

    ... 我不小心将显示比萨饼的 for 循环放在了循环通过配料按钮的 for 循环中。我将其移出一步,并将从比萨饼中删除显示类的部分移到循环数组 itemsToFilter 的 for 循环之前,因为如果数组为空,它不会删除显示类。谢谢大家。

    【讨论】:

      【解决方案2】:

      我重新编写了您的代码并进行了一些更改:

      var itemsToFilter = [];
      
      //HTMLCollections, not arrays
      ingredients = document.getElementsByClassName("filter-item"); 
      pizzas = document.getElementsByClassName("menu-item");
      
      function filter() {
          // Here you have always only the selected ingredients
          let selectedIngredients = ingredients.filter(ingredient => ingredient.checked === true);
      
          if(selectedIngredients.length === 0) {
              pizzas.forEach(pizza => {
                   pizza.classList.add("show");
              });
          } else {
              pizzas.forEach(pizza => {
                  let hasAllIngredients = true;
                  selectedIngredients.forEach(ingredient => {
                      if(!pizza.classList.includes(ingredient.getAttribute("id"))) {
                          hasAllIngredients = false;
                      }
                  });
      
                  if(hasAllIngredients) {
                      pizza.classList.add("show");
                  } else {
                      pizza.classList.remove("show");
                  }
              });
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-08-28
        • 2019-07-26
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        • 2016-06-30
        • 2011-12-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多