如何从数组列表中排除特定HTML标签修复搜索过滤Bug
解决带国旗标签的国家选择器搜索过滤问题
问题根源
你的搜索逻辑直接使用包含HTML标签的字符串进行匹配,导致搜索词会和<span>标签内容(比如flag-icon-afg)或者标签后的空格开头字符匹配,无法正确识别国家名和区号。
解决方案
核心思路是提取每个国家项的纯文本内容,去掉HTML标签后,再和搜索词进行匹配,同时支持匹配国家名或区号(不仅仅是开头匹配)。
步骤1:添加纯文本提取辅助函数
创建一个函数,将带HTML标签的字符串转换为纯文本,并整理成包含国家名和区号的可搜索格式:
function getSearchableContent(htmlStr) { const tempElement = document.createElement('div'); tempElement.innerHTML = htmlStr; // 获取纯文本并去除多余空格 const plainText = tempElement.textContent.trim(); // 把括号里的区号提取出来,和国家名合并成一个可搜索的字符串 // 例如 "Afghanistan (+93)" → "afghanistan +93" return plainText.replace(/\((\+\d+)\)/, ' $1').toLowerCase(); }
步骤2:修改搜索过滤逻辑
替换原搜索事件中的过滤代码,使用上面的辅助函数处理每个国家项,再判断搜索词是否包含在处理后的内容中:
searchInp.addEventListener("keyup", () => { let arr = []; let searchWord = searchInp.value.toLowerCase().trim(); arr = countries.filter(data => { // 用处理后的纯文本进行匹配 const searchableText = getSearchableContent(data); return searchWord ? searchableText.includes(searchWord) : true; }).map(data => { let isSelected = data == selectBtn.firstElementChild.innerHTML ? "selected" : ""; return `<li onclick="updateName(this)" class="${isSelected}">${data}</li>`; }).join(""); options.innerHTML = arr ? arr : `<p style="margin-top: 10px;">Oops! Country not found</p>`; });
修改后的完整JavaScript代码
const wrapper = document.querySelector(".wrapper"), selectBtn = wrapper.querySelector(".select-btn"), searchInp = wrapper.querySelector("input"), options = wrapper.querySelector(".options"); let countries = [ "<span class='flag-icon flag-icon-afg'></span> Afghanistan (+93)", "<span class='flag-icon flag-icon-bel'></span> Belgium (+32)", "<span class='flag-icon flag-icon-chn'></span> China (+86)", "France (+33)", "India (+91)", "Mexico (+52)" ]; // 新增:提取可搜索内容的辅助函数 function getSearchableContent(htmlStr) { const tempElement = document.createElement('div'); tempElement.innerHTML = htmlStr; const plainText = tempElement.textContent.trim(); return plainText.replace(/\((\+\d+)\)/, ' $1').toLowerCase(); } function addCountry(selectedCountry) { options.innerHTML = ""; countries.forEach(country => { let isSelected = country == selectedCountry ? "selected" : ""; let li = `<li onclick="updateName(this)" class="${isSelected}">${country}</li>`; options.insertAdjacentHTML("beforeend", li); }); } addCountry(); function updateName(selectedLi) { searchInp.value = ""; addCountry(selectedLi.innerHTML); wrapper.classList.remove("active"); filterData = /(<span\b[^<>]*><\/span>\s*)\w+(?:\s+\w+)*\s*\((\+[\d-]+)\)/g; selectBtn.firstElementChild.innerHTML = selectedLi.innerHTML.replace(filterData, `$1$2`); } // 修改后的搜索逻辑 searchInp.addEventListener("keyup", () => { let arr = []; let searchWord = searchInp.value.toLowerCase().trim(); arr = countries.filter(data => { const searchableText = getSearchableContent(data); return searchWord ? searchableText.includes(searchWord) : true; }).map(data => { let isSelected = data == selectBtn.firstElementChild.innerHTML ? "selected" : ""; return `<li onclick="updateName(this)" class="${isSelected}">${data}</li>`; }).join(""); options.innerHTML = arr ? arr : `<p style="margin-top: 10px;">Oops! Country not found</p>`; }); selectBtn.addEventListener("click", () => wrapper.classList.toggle("active")); document.addEventListener('click', (event)=> { if (!wrapper.contains(event.target)) { wrapper.classList.remove("active"); }else{ wrapper.classList.add("active"); } });
效果说明
- 搜索
Afghanistan或93都能匹配到阿富汗选项 - 搜索
Belgium或32能匹配比利时 - 带span标签和不带span标签的项都能正常搜索
- 支持模糊匹配(搜索词出现在任意位置都能匹配)
内容的提问来源于stack exchange,提问作者Gupa Dutta
相关产品推荐
相关产品推荐

