使用keyup事件过滤已加载JSON文件中爬行动物数据的技术求助
问题分析与修复方案
我看了你的代码,发现几个导致搜索功能失效的关键问题,咱们一步步来修复:
核心问题梳理
- 数据作用域错误:你在XHR回调里定义的
response是局部变量,搜索事件里根本访问不到;而且你用$.each(Reptiles, ...)遍历的是文件名字符串("ReptilesTX.json"),不是解析后的动物数组。 - DOM元素不存在:搜索代码里用了
#filter-records,但你的HTML里根本没有这个元素,应该复用原来的#postAnimal容器。 - 重复ID冲突:循环里给每个
<ul>和<li>加了相同的id="list"、id="name",ID在页面中必须唯一,改成class才合理。 - 模板字符串语法错误:拼接HTML时结尾多了不必要的分号,搜索回调里还错误地用了
response而不是当前遍历的val。
修正后的完整代码
HTML部分(修正input类型,调整容器标签)
<div id="container"> <form role="form"> <div class="form-group"> <input type="text" class="form-control input-lg" id="txt-search" placeholder="Type your search character"> </div> <div id="postAnimal">Posting goes here</div> </form> </div>
JavaScript部分(重构逻辑,修复所有问题)
// 全局变量保存爬行动物数据,让搜索事件能访问到 let reptileData = []; // 加载JSON数据 const xhr = new XMLHttpRequest(); const reptileFile = "ReptilesTX.json"; xhr.onload = function() { if (this.readyState == 4 && this.status == 200) { reptileData = JSON.parse(this.responseText); // 初始加载所有爬行动物 renderReptiles(reptileData); } }; xhr.open("GET", reptileFile, true); xhr.send(); // 通用渲染函数,避免重复代码 function renderReptiles(data) { let output = ''; data.forEach(reptile => { output += ` <ul class="reptile-list"> <li class="reptile-name">${reptile.friendlyName}</li><br> <li><img src='${reptile.picturePath}.jpg' alt="${reptile.friendlyName}"></li><br> <li><span>Scientific Name: </span>${reptile.scientificName}</li> <li><span>Description: </span>${reptile.description}</li><br> <li><span>Life History: </span>${reptile.lifeHistory}</li><br> <li><span>Habitat: </span>${reptile.habitat}</li><br> <li><span>Distribution: </span>${reptile.distribution}</li> <li><span>Source: </span><a href="${reptile.url}">Site</a></li> </ul> `; }); document.getElementById("postAnimal").innerHTML = output; } // 搜索事件监听 $('#txt-search').keyup(function(){ const searchField = $(this).val().trim(); // 搜索框为空时,重新显示所有数据 if(searchField === '') { renderReptiles(reptileData); return; } // 创建不区分大小写的正则表达式 const regex = new RegExp(searchField, "i"); // 过滤匹配友好名称或学名的条目 const filteredData = reptileData.filter(reptile => { return regex.test(reptile.friendlyName) || regex.test(reptile.scientificName); }); // 渲染过滤后的结果 renderReptiles(filteredData); });
优化说明
- 把渲染逻辑抽成
renderReptiles函数,复用代码更易维护; - 用全局变量
reptileData保存解析后的JSON数据,解决作用域问题; - 用
forEach和filter替代传统循环,更符合现代JavaScript写法; - 给图片添加
alt属性,提升页面可访问性; - 修复了搜索框为空时的逻辑,改为重新显示所有数据而非清空容器。
内容的提问来源于stack exchange,提问作者Felipe Ceballos
相关产品推荐
相关产品推荐

