对el.dataset使用带变量的循环

问题描述 投票:0回答:2

我正在创建一系列过滤器,它目前是“丑陋的代码”。我想输出数组中的所有过滤器,但我无法弄清楚如何将变量赋给元素的dataset属性。 (除了他们正在过滤的内容之外,您会看到每个过滤器的代码完全相同)。

任何人都可以帮我告诉我如何实现这一目标?

function filterList() {
  const itemsNode = document.querySelectorAll(".js-filterable");
  const items = Array.from(itemsNode);

  const filterBrand = document.querySelector(".js-filter-brand");
  const filterState = document.querySelector(".js-filter-state");
  const filterCity = document.querySelector(".js-filter-city");
  const filterOwner = document.querySelector(".js-filter-owner");
  const filtered = document.querySelector(".js-filtered");

  let filterValue;
  let results;

  // Listen for filter changes

  if (filterBrand) {
    filterBrand.addEventListener("input", function(filtered, filterValue) {
      filterValue = this.value;

      if (filterValue === "all") {
        let results = items;
        outputResults(results);
      } else {
        let results = items.filter(item => item.dataset.brand === filterValue);
        outputResults(results);
      }
    });
  }

  if (filterState) {
    filterState.addEventListener("input", function(filtered, filterValue) {
      filterValue = this.value;

      if (filterValue === "all") {
        let results = items;
        outputResults(results);
      } else {
        let results = items.filter(item => item.dataset.state === filterValue);
        outputResults(results);
      }
      
    });
  }

  if (filterCity) {
    filterCity.addEventListener("input", function(filtered, filterValue) {
      filterValue = this.value;

      if (filterValue === "all") {
        let results = items;
        outputResults(results);
      } else {
        let results = items.filter(item => item.dataset.city === filterValue);
        outputResults(results);
      }
    });
  }

  if (filterOwner) {
    filterOwner.addEventListener("input", function(filtered, filterValue) {
      filterValue = this.value;

      if (filterValue === "all") {
        let results = items;
        outputResults(results);
      } else {
        let results = items.filter(item => item.dataset.owner === filterValue);
        outputResults(results);
      }
    });
  }

  // Update filtered list

  function outputResults(results) {
    while (filtered.firstChild)
      filtered.removeChild(filtered.firstChild);
    results.forEach(function(result) {
      filtered.appendChild(result);
    });
  }
}
javascript loops
2个回答
0
投票

看起来你只是希望它是DRYer:

function filterList() {

  const itemsNode     = document.querySelectorAll(".js-filterable");
  const items         = Array.from(itemsNode);
  const filterClasses = ['brand', 'state', 'city', 'owner']

  filterClasses.forEach(filterClass => {
    const filtered = document.querySelector(`.js-filter-${filterClass}`);

    if (filtered) {
      filtered.addEventListener("input", function(filtered, filterValue) {

        filterValue = this.value;         // <-- why overwrite the param?
        let results;
        if (filterValue === "all")
          results = items;
        else
          results = items.filter(item => item.dataset[filterClass] === filterValue);
          
        outputResults(results);
      });
    }
  })
}


// Update filtered list
function outputResults(results) {
  const filteredItems = document.querySelector(".js-filtered");

  while (filteredItems.firstChild)
    filteredItems.removeChild(filteredItems.firstChild);

  results.forEach(result => filteredItems.appendChild(result));
}

特别注意:

  • filterClasses = ['brand', 'state', 'city', 'owner']用于迭代已知的类名
  • 使用item.dataset[filterClass],变量用于设置数据值

0
投票

我想你可以从这样的事情开始:

const passThru = (x) => true;

// Return a filter function using the given property name 
const filterPropName = (propName, filterValue) => filterValue === "all" ?
        passThru : 
        ({dataset}) => dataset[propName] === filterValue;

// ...

function createListener (propName) {
    return () => {
      const filterValue = this.value;
      const results = items.filter(filterPropName(propName, filterValue));
      outputResults(results);       
    }
}

if (filterBrand) {
    filterBrand.addEventListener("input", createListener("brand"));
}

if (filterState) {
    filterState.addEventListener("input", createListener("state"));
}

// Etc.
© www.soinside.com 2019 - 2024. All rights reserved.