如何为从API获取的加密货币数据实现搜索筛选功能
问题核心原因
- 搜索框的
keyup事件被绑定在map遍历循环中,每遍历1条加密货币数据就会重复绑定1次事件,最终触发搜索时会执行几十次重复逻辑,导致渲染结果混乱 - 没有对接口返回的完整加密货币数组做持久化存储,每次搜索只能拿到单次循环内的单条数据,无法做全局筛选
- 接口返回的
data.data本身就是标准数组,完全可以正常调用filter方法,你之前的判断有误
修复实现
我们把逻辑拆分为数据存储、列表渲染、搜索筛选三个独立模块,即可实现需求,修复后的完整JavaScript代码如下:
let dataaa = document.querySelector(".dataaa"); let searchbar = document.getElementById("searchbar"); // 存储全量加密货币数据 let cryptoList = []; // 封装列表渲染函数,传入要展示的数组即可渲染对应内容 function renderList(list) { if (list.length === 0) { dataaa.innerHTML = `<div class="pieceofdata"><h1 class= "symbol"> </h1><h1 class= "name"></h1> <h1 class="name">No Results Found</h1> <h1 class= "price"></h1></div>`; return; } const htmlStr = list.map(pieceofdata => { const name = pieceofdata.slug; const symbol = pieceofdata.symbol; const price = +pieceofdata.metrics.market_data.price_usd.toFixed(2); return `<div class="pieceofdata"><h1 class= "symbol"> ${symbol}</h1><h1 class= "name"> ${name}</h1><h1 class="price"> $${price}</h1></div>`; }).join(''); dataaa.innerHTML = htmlStr; } function getdata() { fetch( 'https://data.messari.io/api/v1/assets?fields=id,slug,symbol,metrics/market_data/price_usd' ) .then(response => response.json()) .then(data => { // 存储全量数据 cryptoList = data.data; // 首次渲染全量列表 renderList(cryptoList); }); } // 搜索事件仅绑定一次 searchbar.addEventListener('keyup', function(e){ const keyword = e.target.value.trim().toLowerCase(); // 输入为空时直接展示全量列表 if (!keyword) { renderList(cryptoList); return; } // 筛选同时匹配名称或币种代码,忽略大小写 const filteredList = cryptoList.filter(item => item.slug.toLowerCase().includes(keyword) || item.symbol.toLowerCase().includes(keyword) ); renderList(filteredList); }) getdata();
逻辑说明
- 用全局变量
cryptoList存储接口返回的全量加密货币数据,后续所有筛选操作都基于这个数组执行 - 封装独立的
renderList渲染函数,不管是首次渲染还是搜索后渲染都调用这个方法,避免逻辑重复 - 搜索事件全局仅绑定一次,每次用户输入时先对关键词做小写处理,筛选同时匹配加密货币名称和币种代码,大小写不敏感,使用体验更好
- 搜索关键词为空时自动恢复展示全量列表,符合常规搜索框交互逻辑
内容的提问来源于stack exchange,提问作者Matthew schlegel
相关产品推荐
相关产品推荐

