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的项。
解决方案
错误原因
- 数组未初始化:当
sessionStorage中没有arrayIDs时,JSON.parse返回null,后续调用arrayIDs.includes()或arrayIDs.push()会直接报错,导致逻辑中断,引发异常。 - 逻辑判断漏洞:else分支直接执行移除操作,但忽略了两种场景:
- 符合筛选条件但ID已在数组中,此时不需要操作
- 不符合筛选条件但ID原本不在数组中,
indexOf(id)返回-1,splice(-1,1)会移除数组最后一个元素,最终导致数组被清空
- 频繁写入sessionStorage:循环内每次修改都写入存储,既影响性能,也可能导致数据不一致。
修复步骤
- 初始化数组:获取
arrayIDs时,若为null则初始化为空数组 - 拆分判断逻辑:明确四种场景的处理规则,避免误操作
- 统一写入存储:循环结束后再更新sessionStorage,减少IO操作
- 调用显示函数:操作完成后执行
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
相关产品推荐
相关产品推荐

