基于双数组模拟REST响应,如何实现分类唯一显示的导航?
嘿,我来帮你搞定这个导航渲染的问题!你现在的问题根源在于嵌套循环的逻辑——每找到一个匹配分类的链接,就会重新渲染一次分类标题,所以才会重复出现。我们换个思路,先把链接按分类分组,再逐个分类渲染标题和对应的所有链接,这样就能实现你想要的效果啦。
解决步骤
- 第一步:把
links数组按分类名称分组,生成一个以分类名为键、对应链接数组为值的对象,这样每个分类下的所有链接就都聚在一起了。 - 第二步:遍历你的
categoryArr,对每个分类:- 创建分类容器和标题
- 找到该分类对应的所有链接,渲染成链接列表
- 把标题和链接列表塞进容器,再添加到DOM里
修改后的完整代码
JavaScript
var links = [ { "__metadata": { "id": "", "uri": "http://www.whatever.com" }, "Id": 1, "Title": "Link 01 - test category 01", "Link": "https://www.google.com", "Category": { "__metadata": { "type": "" }, "results": [ "Test Category 01" ] }, "Image": null, "ID": 1 }, { "__metadata": { "id": "", "uri": "http://www.whatever.com", "etag": "", "type": "" }, "Id": 2, "Title": "Link 02 - test category 01", "Link": "https://www.google.com", "Category": { "__metadata": { "type": "" }, "results": [ "Test Category 01" ] }, "Image": null, "ID": 2 }, { "__metadata": { "id": "", "uri": "http://www.whatever.com", "etag": "", "type": "" }, "Id": 3, "Title": "Link 01 - test category 02", "Link": "https://www.google.com", "Category": { "__metadata": { "type": "" }, "results": [ "Test Category 02" ] }, "Image": null, "ID": 209 }, { "__metadata": { "id": "", "uri": "http://www.whatever.com", "etag": "", "type": "" }, "Id": 210, "Title": "Link 02 - test category 02", "Link": "https://www.somerandomdomain.com", "Category": { "__metadata": { "type": "" }, "results": [ "Test Category 02" ] }, "Image": null, "ID": 210 } ]; var categoryArr = [ "Test Category 01", "Test Category 02", "Test Category 03" ]; var menu = $("#output2"); // 第一步:按分类分组链接 var linksByCategory = {}; links.forEach(function(link) { // 取分类名称(这里假设每个链接只有一个分类) var categoryName = link.Category.results[0]; if (!linksByCategory[categoryName]) { linksByCategory[categoryName] = []; } linksByCategory[categoryName].push(link); }); // 第二步:遍历分类,渲染每个分类的导航块 $.each(categoryArr, function(catIndex, category) { // 创建分类容器 var navContainer = $('<div>').addClass('navContainer'); // 添加分类标题 var categoryTitle = $('<div>').addClass('title').text(category); navContainer.append(categoryTitle); // 创建链接列表容器 var linksWrapper = $('<div>').addClass('links'); var linkList = $('<ul>'); // 获取当前分类的所有链接,没有的话就是空数组 var categoryLinks = linksByCategory[category] || []; // 渲染每个链接 categoryLinks.forEach(function(link) { var listItem = $('<li>'); var linkElement = $('<a>').attr('href', link.Link).text(link.Title); listItem.append(linkElement); linkList.append(listItem); }); linksWrapper.append(linkList); navContainer.append(linksWrapper); // 把整个分类块添加到页面 menu.append(navContainer); });
CSS
.navContainer { border: 1px solid grey; margin: 10px; padding:5px; } .links ul li { list-style-type:none; } .title { font-weight: bold; margin-bottom: 8px; }
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="output2"></div> <hr> <!-- result should be like this --> <h5> Result should look like this below </h5> <div class="navContainer"> <div class="title">Category title</div> <div class="links"> <ul> <li><a href="#">http://www.google.com</a></li> <li><a href="#">http://www.google.com</a></li> <li><a href="#">http://www.google.com</a></li> </ul> </div> </div> <div class="navContainer"> <div class="title">Category title</div> <div class="links"> <ul> <li><a href="#">http://www.google.com</a></li> <li><a href="#">http://www.google.com</a></li> <li><a href="#">http://www.google.com</a></li> </ul> </div> </div>
关键说明
- 分组逻辑:我们用
linksByCategory对象把所有链接按分类归类,这样后续渲染时不用再反复遍历整个links数组找匹配项,效率更高,也避免了重复渲染标题。 - 空分类处理:如果某个分类(比如Test Category 03)没有对应的链接,代码会渲染一个只有标题的容器,如果你想隐藏这类空分类,可以在渲染前加个判断:
if (categoryLinks.length === 0) return;,这样就不会渲染空分类块了。 - DOM结构优化:现在的DOM结构和你想要的示例完全一致,每个分类块包含标题和链接列表,结构更清晰。
内容的提问来源于stack exchange,提问作者VanCoon
相关产品推荐
相关产品推荐

