You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击列表项按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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:15:02