我正在创建一系列过滤器,它目前是“丑陋的代码”。我想输出数组中的所有过滤器,但我无法弄清楚如何将变量赋给元素的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);
});
}
}
看起来你只是希望它是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]
,变量用于设置数据值我想你可以从这样的事情开始:
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.