在输入中使用"keyup"时如何过滤/显示结果(来自 JSON 数据)?



当事件侦听器"keyup";激活。问题是,当我显示产品时,它不会过滤任何内容(但在console.log中,所有内容都正确过滤(,但只显示数组中的前3个项目,而不显示过滤的项目。

在对数组使用map方法时,我尝试过使用slice(0,3)

我做错了什么?

这是代码:

var url = '/dataset.json';
let produits = [];
var productsList = document.getElementById("productsList")
const searchBar = document.getElementById('searchbar')
const noResults = document.getElementById('no-results')
// get data from JSON
fetch(url)
.then(res => res.json())
.then((output) => {
produits = output
console.log(produits)
displayProducts(produits)
})
.catch(err => { throw err });

// Function that returns <li> items
const displayProducts = (produits) => {
const htmlString = produits
.slice(0, 3)
.map((produit) => {
return `
<li class="produitWrapper">
<div class="imgProduit">
<img src="https://d1tydw6090df56.cloudfront.net/products/320x240/${produit.imageKeyHashes}.jpg"
alt="">
</div>
<div class="infosProduit">
<h2>${produit.title} - </h2>
<h3>${produit.mpn}</h3>
<br>
<p>${produit.description}</p>
</div>
</li>
`;
})
.join("");
productsList.innerHTML = htmlString;
}
searchBar.addEventListener('keyup', (e) => {
const searchString = e.target.value.toLowerCase();
const produitsFiltres = produits.filter(item => {
// noResults.style.display = "block";)
return (
item.mpn.toLowerCase().includes(searchString) ||
item.description.toLowerCase().includes(searchString) ||
item.title.toLowerCase().includes(searchString)
)
});
console.log(produitsFiltres)
})

据我所知,您无论如何都忘记了调用显示产品,下面的代码可以使用

let products = [{name: "andam"}, {name: "hiwa"}, {name: "Abd"}, {name: "Ev"}];
var productsList = document.getElementById("productsList")
const searchBar = document.getElementById('searchbar')

// Function that returns <li> items
const displayProducts = (products) => {
const htmlString = products.slice(0, 3).map((product) => { return `<li>${product.name}</li>`; }).join("");
productsList.innerHTML = htmlString;
}
searchBar.addEventListener('keyup', (e) => {
const searchString = e.target.value.toLowerCase();
const produitsFiltres = products.filter(item => {
return (
item.name.toLowerCase().includes(searchString)
)
});


displayProducts(produitsFiltres)
})
<input id="searchbar"/>
<ul id="productsList"></ul>

我认为您必须再次调用以下函数来重新绘制HTML:这一次过滤后的值显示产品(产品过滤器(

我希望这是正确的答案:(

您不应该在promise的then中返回output并通过const produits = fetch...分配它吗?

无论如何,一旦你有了对象列表,你就可以在需要显示的时候从中进行筛选。不要重新分配produits变量。请确保它是const,因为您总是希望在开始筛选时以原始列表开头。

我在下面创建了一个通用的listToHtml函数。您可以简单地通过传入元素、列表和业务逻辑来调用它。它极大地简化了代码,使其可读性提高了1000%。

const baseUrl = 'https://d1tydw6090df56.cloudfront.net/products/320x240';
const productsList = document.getElementById('products-list');
const searchBar = document.getElementById('searchbar');
const produits = [
{ imageKeyHashes: '',  title: "Apple",  mpn: '', description: "A red fruit" },
{ imageKeyHashes: '',  title: "Banana", mpn: '', description: "A yellow fruit" },
{ imageKeyHashes: '',  title: 'Cherry', mpn: '', description: "A red fruit" },
{ imageKeyHashes: '',  title: 'Pear',   mpn: '', description: "A green fruit" }
];
const renderProduit = (produit) => `
<li class="produit-wrapper">
<div class="img-produit">
<img src="${baseUrl}/${produit.imageKeyHashes}.jpg" alt="">
</div>
<div class="infos-produit">
<h2>${produit.title}</h2>
<h3>${produit.mpn}</h3>
<br>
<p>${produit.description}</p>
</div>
</li>`;
const listToHtml = (targetElement, collection, rendererFn, predicateFn, limit) =>
targetElement.innerHTML = collection
.filter(predicateFn)
.slice(0, limit)
.map(rendererFn)
.join('');
const displayProducts = (searchString) => {
listToHtml(productsList, produits, renderProduit, item => {
return (
searchString === '' ||
item.mpn.toLowerCase().includes(searchString) ||
item.description.toLowerCase().includes(searchString) ||
item.title.toLowerCase().includes(searchString)
)
}, 3);
};
const triggerEvent = (el, eventName) => {
var event = document.createEvent('HTMLEvents');
event.initEvent(eventName, true, false);
el.dispatchEvent(event);
};
searchBar.addEventListener('keyup', e => {
displayProducts(e.target.value.trim().toLowerCase());
});
triggerEvent(searchBar, 'keyup');
h2, h3, p { margin: 0.1em; }
.produit-wrapper { list-style: none; }
<div>
<label>Search</label>
<input type="text" id="searchbar" />
</div>
<div id="products-list"></div>

最新更新