如何通过JavaScript获取自定义导航栏的值实现产品筛选
自定义导航栏实现产品筛选方案
前置规范修正
你现有代码存在两处不符合HTML规范的问题,可能导致取值异常,建议先做修正:
<li>元素原生仅允许作为<ul>/<ol>的子元素,直接放在<nav>下会触发HTML校验错误,建议在nav内嵌套一层ul承载导航项<li>的原生value属性仅在有序列表<ol>内生效,作用是标记列表项序号,普通场景下直接赋值存储分类ID会有兼容问题,推荐使用data-*自定义属性存储业务值
修正后的基础HTML结构:
<nav id="shop-nav" class="nav"> <ul class="nav-list"> <!-- 导航项通过JS动态生成 --> </ul> </nav>
修正后的导航项生成代码
const nav = document.querySelector('#shop-nav .nav-list') // 清空容器避免重复渲染 nav.innerHTML = '' categories.forEach(category => { const navItem = document.createElement('li') navItem.innerText = category.name // 用data-id存储分类ID navItem.dataset.id = category.id navItem.classList.add('nav-item') nav.appendChild(navItem) }) // 默认选中第一个导航项 const firstItem = nav.querySelector('.nav-item:first-child') if (firstItem) firstItem.classList.add('active')
点击取值+筛选逻辑实现
用事件委托的方式给导航绑定点击事件,不需要给每个动态生成的li单独绑定事件,性能更好,也能兼容后续动态追加的导航项:
nav.addEventListener('click', (e) => { const target = e.target // 仅处理导航项的点击事件 if (!target.classList.contains('nav-item')) return // 切换选中态 nav.querySelectorAll('.nav-item').forEach(item => item.classList.remove('active')) target.classList.add('active') // 获取当前选中的分类ID const selectedCategoryId = target.dataset.id // 执行产品筛选 renderFilteredProducts(selectedCategoryId) }) // 产品筛选逻辑,可根据自己的业务数据调整 function renderFilteredProducts(categoryId) { const allProducts = document.querySelectorAll('.product-card') allProducts.forEach(product => { // 匹配当前分类则显示,否则隐藏;如果有全部分类项可单独判断id为all的场景 if (product.dataset.category === categoryId || categoryId === 'all') { product.style.display = 'block' } else { product.style.display = 'none' } }) }
配套参考样式
给导航项加基础交互和选中态视觉效果:
.nav-list { list-style: none; padding: 0; margin: 0; display: flex; gap: 8px; } .nav-item { padding: 8px 16px; cursor: pointer; border-radius: 4px; transition: background 0.2s; } .nav-item:hover { background: #f3f4f6; } .nav-item.active { background: #2563eb; color: #fff; }
如果你一定要沿用直接给li赋值value的写法,也可以通过
e.target.value直接读取值,但该写法不符合HTML语义规范,不推荐使用。
内容的提问来源于stack exchange,提问作者Aleksandar Stevanovic
相关产品推荐
相关产品推荐

