我有一个搜索功能,它使用 JavaScript 来过滤 html 列表。
默认情况下,所有列表项都是隐藏的,但如果用户输入正确的关键字,则会显示。
目前搜索仅返回与输入完全匹配的项目。
如果遗漏某个单词、添加了其他单词或单词顺序不同,则不会显示结果。
我希望用户能够搜索多个单词,如果一个或多个单词匹配,则会显示结果。
用户输入单词的顺序并不重要。
例如,搜索 ‘VAUXHALL CORSA DIESEL’ 将返回列表项 ‘BLUE VAUXHALL CORSA 1.6L DIESEL。’
搜索 ‘DIESEL VAUXHALL’ 也会返回相同的列表项。
我认为这可以通过合并 .split(“ ”) 来完成,但是我不确定代码中的哪个点需要它。
我尝试了一些配置,但没有成功。
我对编码很陌生!
我已经添加了当前脚本。
window.addEventListener("load", () => {
var filter = document.getElementById("filter"),
list = document.querySelectorAll(".list li");
filter.onkeyup = () => {
let search = filter.value.toLowerCase();
for (let i of list) {
let item = i.innerHTML.toLowerCase();
if (item.indexOf(search) == -1) {
i.classList.add("hide");
} else {
i.classList.remove("hide");
if (filter.value.length == 0) {
i.classList.add("hide");
}
}
}
};
});
您可以
split
在空白处进行搜索。
例如
let searchKeywords = filter.value.toLowerCase().split(" ");
并使用
every
数组函数检查搜索中的每个关键字是否contains
。
完整的代码示例。
window.addEventListener("load", () => {
var filter = document.getElementById("filter"),
list = document.querySelectorAll(".list li");
filter.onkeyup = () => {
let searchKeywords = filter.value.toLowerCase().split(" ");
for (let i of list) {
let item = i.innerHTML.toLowerCase();
if (searchKeywords.every(word => item.includes(word))) {
i.classList.add("hide");
} else {
i.classList.remove("hide");
if (filter.value.length == 0) {
i.classList.add("hide");
}
}
}
};
});
window.addEventListener("load", () => {
var filter = document.getElementById("filter"),
list = document.querySelectorAll(".list li");
filter.onkeyup = () => {
let search = filter.value.toLowerCase();
for (let i of list) {
let item = i.innerHTML.toLowerCase();
if (item.indexOf(search) == -1) {
i.classList.add("hide");
} else {
i.classList.remove("hide");
if (filter.value.length == 0) {
i.classList.add("hide");
}
}
}
};
});
我猜到了一些 HTML
这可以满足您使用
.every
和 .includes
的要求
我也使用输入代替,因为用户可以粘贴到字段中 最后我简化了隐藏
window.addEventListener("load", () => {
const list = document.querySelector(".list")
filter = document.getElementById("filter"),
lis = [...list.querySelectorAll("li")]; // spread to use map and sort
filter.addEventListener("input", () => {
let search = filter.value.toLowerCase().split(/\W+/);
lis.forEach(li => {
if (search.length === 0) {
li.hidden = true;
li.dataset.rank = 0;
return
}
let items = li.textContent.toLowerCase().split(/\W+/)
li.hidden = !search.every(flt => items.includes(flt))
li.dataset.rank = search.filter(flt => items.includes(flt)); // how many
});
lis.sort((a, b) => a.dataset.rank - b.dataset.rank).forEach(li => list.append(li))
});
});
For example, searching ‘VAUXHALL CORSA DIESEL’ would return the list item, Searching ‘DIESEL VAUXHALL’ would also return the same list item.
<hr/>
<input type="text" id="filter" />
<ul class="list">
<li>BLUE VAUXHALL CORSA 1.6L DIESEL</li>
<li>RED DIESEL</li>
<li>GREEN VAUXHALL ASTRA 1.6L PETROL</li>
<li>RED VAUXHALL CORSA 1.6L DIESEL</li>
<li>RED VAUXHALL CORSA 1.6L PETROL</li>
<li>RED VAUXHALL ASTRA 1.6L PETROL</li>
<li>RED VAUXHALL ASTRA 1.6L DIESEL</li>
</ul>