如何创建不可变数组解决列表过滤修改条件无法匹配全量原始数据问题
问题根因
document.getElementsByClassName返回的是实时动态的HTMLCollection集合,页面DOM变更(比如过滤后移除不符合条件的元素)时集合会自动同步更新,所以你定义的itemWrappers变量无法保留初始全量数据。
修复步骤
1. 页面加载时创建全量数据静态快照
在页面首次渲染完成、所有列表元素都加载完毕后,将动态集合转成静态数组,同时预存ID和对应文本的映射表,避免每次过滤重复读取DOM属性,提升性能:
// 预存id和对应文本的映射表,页面加载完成后仅初始化一次 const itemTextMap = {}; // 将动态集合转为静态数组,不会随DOM变化更新 const initialItemWrappers = Array.from(document.getElementsByClassName('itemWrapperColumns')); initialItemWrappers.forEach(el => { const id = el.getAttribute('data-id'); // 提前转成大写,后续过滤不用重复转换 itemTextMap[id] = el.innerText.toUpperCase(); })
2. 优化过滤逻辑
删除原有依赖动态itemWrappers的代码,直接基于预存的静态映射表过滤:
function itemFilter(){ const input = document.getElementById('userFilter'); // 处理过滤条件:去空、统一转大写 const filterKeys = input.value.split(',') .map(key => key.trim().toUpperCase()) .filter(key => key); if (filterKeys.length === 0) return Object.keys(itemTextMap); // 筛选符合所有过滤条件的ID return Object.keys(itemTextMap).filter(id => { return filterKeys.every(key => itemTextMap[id].includes(key)); }) }; // 原有newItemsList、触发逻辑无需修改 function newItemsList() { var filterInput = document.getElementById('userFilter'); if (filterInput.value == ''){ var itemList = items; }else{ var itemList = items.filter(val => itemFilter().includes(val.id)); } return itemList }; $('#userFilter').keyup(function(event) { if (event.keyCode === 13) {displayingItems(newItemsList())} });
内容的提问来源于stack exchange,提问作者ConfusedSpark
相关产品推荐
相关产品推荐

