【问题标题】:How do I filter/show results (from JSON data) when using "keyup" on input?在输入上使用“keyup”时如何过滤/显示结果(来自 JSON 数据)?
【发布时间】:2021-01-16 08:40:35
【问题描述】:

当事件侦听器“keyup”激活时,我试图仅显示数组中的 3 个项目,因为我过滤它们。 问题是当我 显示 产品时它没有过滤任何内容(但在 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)
})

【问题讨论】:

  • 也许是因为你在打电话,.slice(0, 3)?另外,您不应该在承诺的then 中返回produits 并分配它const produits = fetch...

标签: javascript arrays dictionary dom filter


【解决方案1】:

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

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>

【讨论】:

    【解决方案2】:

    我认为您必须再次调用以下函数来重新绘制 HTML: 这次使用过滤后的值 displayProducts(produitsFiltres)

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

    【讨论】:

    • 你是对的!我正在安慰记录所有内容并忘记调用该函数。感谢您的帮助!
    【解决方案3】:

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

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

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

    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>

    【讨论】:

      猜你喜欢
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-27
      • 2017-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多