我试图编写一个搜索/过滤功能,根据用户键入的内容搜索带有data- *属性的无序列表项。
<input type="text" placeholder="Search..." id="myInput" onkeyup="myFunction()">
<ul id="myUL">
<li><a href="#" data-keywords="photography">Digital Media Design</a></li>
<li><a href="#" data-keywords="computers">Information Technology</a></li>
<li><a href="#" data-keywords="coding">Programming</a></li>
</ul>
这是我到目前为止的代码,它仅适用于一个数据关键字项。我需要帮助才能根据多个关键字调出搜索结果。
<li><a href="#" data-keywords="photography photoshop illustrator premiere">Digital Media Design</a></li>
// Search functionality
function myFunction() {
// Declare variables
var input, filter, ul, li, a, i;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
li = ul.getElementsByTagName('li');
// Loop through all list items, and hide those who don't match the search query
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1 || $(a).data("keywords") === filter.toLocaleLowerCase()) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
如果有人建议我如何改进那些令人敬畏的代码!
答案 0 :(得分:0)
这对我有用:
// Get all li's and create an array with each li's data attributes
const lis = document.querySelector("#myUL").children;
const keywordArray = [];
[...lis].forEach((li, i) => {
keywordArray.push(li.children[0].dataset.keywords);
});
function myFunction() {
//Show any previous hidden li's
[...lis].forEach(li => {
li.style.display = 'block';
});
const inputArray = document.querySelector('#myInput').value.split(' ');
const indexes = [];
// For each word in the input field, search through our data attribute array
inputArray.forEach(term => {
keywordArray.forEach((keywords, i) => {
keywords.split(' ').forEach(keyword => {
// If we find a match, add the index of the data attribute array, which
// will be the same as the index of the li element
if (keyword === term) {
indexes.push(i);
}
});
});
});
// If we have a match, hide every non-matching li'
if (indexes.length) {
[...lis].forEach((li, i) => {
if (!indexes.includes(i)) {
li.style.display = 'none';
}
});
}
}
为了澄清,您是否希望使用其他搜索字词来使搜索更具体或更不具体?因为我的解决方案使搜索不那么具体,因为它会显示任何匹配任何搜索词的li。
答案 1 :(得分:0)
我做了一些假设:
最需要解释的是那个正则表达式。它使用标准技巧进行and
匹配:
Regular Expressions: Is there an AND operator?
因此,如果您搜索digital photography
,RegExp将等同于:
/(?=.*digital)(?=.*photography)/i
如果您希望搜索or
而不是and
,则只需相应地调整RegExp即可。如果你想做一个start-with匹配而不是substring,你可以在每个搜索词之前输入\b
(在字符串中适当地转义为\\b
)。
我希望其余的都是不言自明的,我试着接近问题中的代码。
// Search functionality
function myFunction() {
// Declare variables
var input = document.getElementById('myInput'),
filter = input.value,
ul = document.getElementById('myUL'),
lis = ul.getElementsByTagName('li'),
searchTerms = filter.match(/[a-z]+/gi),
re, index, li, a;
if (searchTerms) {
searchTerms = searchTerms.map(function(term) {
return '(?=.*' + term + ')';
});
re = new RegExp(searchTerms.join(''), 'i');
} else {
re = /./;
}
// Loop through all list items, and hide those who don't match the search query
for (index = 0; index < lis.length; index++) {
li = lis[index];
a = li.firstChild;
if (re.test(a.innerHTML + ' ' + a.getAttribute('data-keywords'))) {
li.style.display = '';
} else {
li.style.display = 'none';
}
}
}
&#13;
<input type="text" placeholder="Search..." id="myInput" onkeyup="myFunction()">
<ul id="myUL">
<li><a href="#" data-keywords="photography photoshop illustrator premiere">Digital Media Design</a></li>
<li><a href="#" data-keywords="computers">Information Technology</a></li>
<li><a href="#" data-keywords="coding">Programming</a></li>
</ul>
&#13;