题解 | #智能提示#
智能提示
https://www.nowcoder.com/practice/efccf73b4ceb4446b6d71127f874e6d3
// items 为字符串数组 function suggest(items) { let inputValue = document.querySelector('.js-input').value // 1.输入框的值需要移除两侧空白 inputValue = inputValue.trim() // 2.输入框为空,按不匹配处理(移除所有li,隐藏.js-suggest节点) let jsSuggest = document.querySelector('.js-suggest') let ul = jsSuggest.querySelector('.js-suggest ul') if (inputValue.length == 0) { ul.innerHTML = '' jsSuggest.classList.add('hide') return } // 3.字符串使用模糊匹配,比如"北大"能匹配"北大"和"北京大学",但不能匹配"大北京",即按照 /北.*?大.*?/ 这个正则进行匹配 // 3.1生成正则字符串 let regexpStr = '' for (let s of inputValue) { // 特殊字符,需要转义,写两个\是因为,字符串'\\'虽然看上去是两条\,但是呢,字符串显示这些特殊符号,也需要转义,会消耗掉一个\,然后就只剩下了一个\,用于给正则用于转义,这样两个\就刚好用完了 if (['(', ')', '[', ']', '{', '}', '^', '$', '.', '|', '?', '*', '+'].includes(s)) s = `\\${s}` regexpStr += s + '.*?' } regexpStr = regexpStr.slice(0, regexpStr.length - 3) // 3.2生成正则对象 let regexp = new RegExp(regexpStr) // 3.3遍历items,挨个去匹配,过滤出能匹配的数组项 let renderItemsArr = items.filter(item => item.match(regexp) !== null) // 通过在.js-suggest节点上添加/移除 hide 这个class来控制该节点的隐藏/显示 // 4.当items中的字符串和输入框值匹配时,将匹配数据渲染在ul的li节点中,并显示.js-suggest节点 if (renderItemsArr.length != 0) { let lis = renderItemsArr.reduce((lis, item) => lis + `<li>${item}</li>`, '') ul.innerHTML = lis jsSuggest.classList.remove('hide') } else { // 5.当items中的字符串和输入框值不匹配时,移除ul下的所有li节点,并隐藏.js-suggest节点 ul.innerHTML = '' jsSuggest.classList.add('hide') } }