JavaScript如何按数组对象属性分组实现分类下拉菜单功能
实现分组逻辑
你现有代码的问题是没有做分类去重和对应分类下商品的归集,只需要用一个对象存储分类和对应商品的映射关系即可实现分组,示例代码如下:
const products = [ { productName: "product A", productCategory: "cat 1" }, { productName: "product B", productCategory: "cat 2" }, { productName: "product C", productCategory: "cat 3" }, { productName: "product D", productCategory: "cat 3" } ]; // 第一步:按分类分组 const groupedMap = {}; products.forEach(item => { // 不存在该分类时先初始化空数组 if (!groupedMap[item.productCategory]) { groupedMap[item.productCategory] = []; } // 把商品加入对应分类 groupedMap[item.productCategory].push(item); });
执行后groupedMap的结构为:
{ "cat 1": [ { productName: "product A", productCategory: "cat 1" } ], "cat 2": [ { productName: "product B", productCategory: "cat 2" } ], "cat 3": [ { productName: "product C", productCategory: "cat 3" }, { productName: "product D", productCategory: "cat 3" } ] }
生成菜单数组
如果需要更方便渲染的数组格式,可以再做一次转换:
const menuList = Object.entries(groupedMap).map(([category, productList]) => { return { categoryName: category, productList: productList } });
转换后menuList是长度为3的数组,每一项对应一个主菜单项,和你需要的结构完全匹配。
下拉菜单渲染示例
以下是基于分组结果的原生JS渲染+CSS实现下拉效果的示例:
<div id="menu"></div> <style> #menu { display: flex; gap: 40px; background: #f5f5f5; padding: 12px 20px; } .menu-item { position: relative; cursor: pointer; } .sub-menu { display: none; position: absolute; top: 100%; left: 0; margin-top: 12px; background: #fff; border: 1px solid #eee; min-width: 120px; } .product-item { padding: 8px 12px; border-bottom: 1px solid #eee; } .product-item:last-child { border-bottom: none; } .menu-item:hover .sub-menu { display: block; } </style> <script> const menuDom = document.querySelector('#menu'); menuList.forEach(menu => { // 生成主菜单节点 const menuItem = document.createElement('div'); menuItem.className = 'menu-item'; menuItem.innerText = menu.categoryName; // 生成子菜单节点 const subMenu = document.createElement('div'); subMenu.className = 'sub-menu'; menu.productList.forEach(product => { const pItem = document.createElement('div'); pItem.className = 'product-item'; pItem.innerText = product.productName; subMenu.appendChild(pItem); }); menuItem.appendChild(subMenu); menuDom.appendChild(menuItem); }); </script>
内容的提问来源于stack exchange,提问作者Jeffrey van Zwam
相关产品推荐
相关产品推荐

