点击列表项按ID过滤select下拉option时二次点击返回空数组问题
问题场景
我希望根据用户点击的元素ID对select option下拉选项进行过滤:
原有实现代码如下:
JS代码
document.querySelectorAll('#item-types').forEach(item => { item.addEventListener('click', () => { const categoriesSelect = document.querySelector('#item-categories') const categoriesOptions = Array.from(categoriesSelect.options); const selectType = item.dataset.typeId; function findMatches(search, categoriesOptions) { return categoriesOptions.filter(option => { return option.value.match(search); }); } categoriesOptions.forEach(option => { option.remove(); option.selected = false; }); const matchArray = findMatches(selectType, categoriesOptions); categoriesSelect.append(...matchArray); }); });
HTML代码
<ul> <li id="item-types" data-type-id="1"> <a href="#"> <div>Type1</div> </a> </li> <li id="item-types" data-type-id="2"> <a href="#"> <div>Type2</div> </a> </li> </ul> <select id="item-categories"> <option value="1">category1</option> <option value="1">category2</option> <option value="1">category3</option> <option value="2">category4</option> <option value="2">category5</option> </select>
现有问题
首次点击任意列表项时可以正常过滤,但第二次点击时返回的options为空数组,无法正常完成筛选。
问题原因
- 重复ID不符合HTML规范:ID在单页面中必须唯一,原有代码给多个
<li>设置了相同的id="item-types",首先需要修改为class="item-types"。 - 核心逻辑错误:每次点击时都从当前已经过滤过的
<select>中读取option列表,第一次过滤后<select>内仅保留了匹配的选项,第二次点击时读取的option列表本身就不完整,自然无法匹配到其他类型的选项。
修复方案
提前缓存所有原始option列表,每次点击都从完整的原始列表中筛选匹配项,再渲染到<select>中即可。
修复后完整代码
修复后的JS代码
// 提前缓存所有原始option,不要每次点击都读取当前select内的选项 const categoriesSelect = document.querySelector('#item-categories') const allOriginalOptions = Array.from(categoriesSelect.options); document.querySelectorAll('.item-types').forEach(item => { item.addEventListener('click', () => { const selectType = item.dataset.typeId; // 从原始全量选项中过滤匹配项 const matchOptions = allOriginalOptions.filter(option => option.value === selectType); // 清空当前select的所有选项 categoriesSelect.innerHTML = ''; // 插入匹配的选项 categoriesSelect.append(...matchOptions); }); });
修复后的HTML代码(仅修改重复ID为class)
<ul> <li class="item-types" data-type-id="1"> <a href="#"> <div>Type1</div> </a> </li> <li class="item-types" data-type-id="2"> <a href="#"> <div>Type2</div> </a> </li> </ul> <select id="item-categories"> <option value="1">category1</option> <option value="1">category2</option> <option value="1">category3</option> <option value="2">category4</option> <option value="2">category5</option> </select>
内容的提问来源于stack exchange,提问作者zyyyzzz
相关产品推荐
相关产品推荐

