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

sessionStorage数组增删异常排查:HTML下拉筛选联动问题

问题

我需要根据多个HTML select的选中状态,对sessionStorage中的数组进行ID的添加或移除操作,之后调用主showOrHide函数,根据数组中的ID是否存在来添加可见性类。要求仅当筛选值为''(即全部)或ID不在数组中时,才将ID添加到数组中。但目前出现异常行为,比如第二次选择时数组会被清空,请问哪里出错了?

HTML代码

<select class="form-select form-control" onChange="filterPersonsEducation()" id="education">
<option value="" selected="selected">Any education</option>
<option value="GT">GT</option>
<option value="CC">CC</option>
<option value="ET">ET</option>
</select>
<div id="accordionPe">
<div class="accordion-item">
<h2 class="accordion-header" data-id="id1" data-education="GT">Alik</h2>
</div>
</div>

JS代码

function filterPersonsEducation() {

    var arrayIDs, arrayEducation, input, filter, ul, li, a, i;
    
    input = document.getElementById('education');
    filter = input.value;
    ul = document.getElementById("accordionPe");
    li = ul.getElementsByClassName('accordion-item');
    arrayIDs = JSON.parse(sessionStorage.getItem('arrayIDs'));
   
    for (i = 0; i < li.length; i++) {
        a = li[i].getElementsByClassName("accordion-header")[0].dataset['education']
        id = li[i].getElementsByClassName("accordion-header")[0].dataset['id']
        var arrayEducation = a.split(', ');
            if ((filter === "" || arrayEducation.includes(filter)) && (!arrayIDs.includes(id))) {
                        arrayIDs.push(id);
                        sessionStorage.setItem('arrayIDs', JSON.stringify(arrayIDs));
                        console.log('added ' + id)
                }
            else {
                arrayIDs.splice(arrayIDs.indexOf(id), 1)
                sessionStorage.setItem('arrayIDs', JSON.stringify(arrayIDs));
        console.log('removed ' + id)

            }
            
    }
}

需求是实现两个select联动,只显示对应ID的项。


解决方案

错误原因

  1. 数组未初始化:当sessionStorage中没有arrayIDs时,JSON.parse返回null,后续调用arrayIDs.includes()或arrayIDs.push()会直接报错,导致逻辑中断,引发异常。
  2. 逻辑判断漏洞:else分支直接执行移除操作,但忽略了两种场景:
    • 符合筛选条件但ID已在数组中,此时不需要操作
    • 不符合筛选条件但ID原本不在数组中,indexOf(id)返回-1,splice(-1,1)会移除数组最后一个元素,最终导致数组被清空
  3. 频繁写入sessionStorage:循环内每次修改都写入存储,既影响性能,也可能导致数据不一致。

修复步骤

  1. 初始化数组:获取arrayIDs时,若为null则初始化为空数组
  2. 拆分判断逻辑:明确四种场景的处理规则,避免误操作
  3. 统一写入存储:循环结束后再更新sessionStorage,减少IO操作
  4. 调用显示函数:操作完成后执行showOrHide实现可见性控制

修复后的JS代码

function filterPersonsEducation() {
    var arrayIDs, arrayEducation, input, filter, ul, li, a, i, id;
    
    input = document.getElementById('education');
    filter = input.value;
    ul = document.getElementById("accordionPe");
    li = ul.getElementsByClassName('accordion-item');
    // 初始化数组,避免null引发报错
    arrayIDs = JSON.parse(sessionStorage.getItem('arrayIDs')) || [];
   
    for (i = 0; i < li.length; i++) {
        a = li[i].getElementsByClassName("accordion-header")[0].dataset.education;
        id = li[i].getElementsByClassName("accordion-header")[0].dataset.id;
        arrayEducation = a.split(', ');
        
        const meetsFilter = filter === "" || arrayEducation.includes(filter);
        const idInArray = arrayIDs.includes(id);
        
        if (meetsFilter) {
            if (!idInArray) {
                arrayIDs.push(id);
                console.log('added ' + id);
            }
        } else {
            if (idInArray) {
                const index = arrayIDs.indexOf(id);
                arrayIDs.splice(index, 1);
                console.log('removed ' + id);
            }
        }
    }
    
    // 统一写入sessionStorage
    sessionStorage.setItem('arrayIDs', JSON.stringify(arrayIDs));
    // 执行显示/隐藏逻辑
    showOrHide();
}

额外建议

  • 多select联动场景,建议整合所有筛选条件后统一计算需保留的ID数组,避免单个select处理时的逻辑冲突
  • showOrHide函数可优化为:遍历所有项,根据ID是否在arrayIDs中添加/移除可见性类

内容的提问来源于stack exchange,提问作者HBMCS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:42:21