假设您有100个名字的列表:
<ul>
<li>Randy Hilpert</li>
<li>Peggie Jacobi</li>
<li>Ethelyn Nolan Sr.</li>
<!-- and then some -->
</ul>
...或文件名或电话号码,等等。而且您想在客户端过滤它们,这意味着您没有在服务器端请求搜索数据并返回结果。您只想输入“ rand”并使其过滤列表以包括“ Randy Hilpert”和“ Danika Randall”,因为它们中都包含该字符串。其他所有内容均未包含在结果中。
让我们看看如何使用不同的技术来做到这一点。
CSS可以八九不离十做到这一点
CSS不能根据它们包含的内容来选择项目,但是可以根据属性和这些属性的值进行选择(利用CSS的属性选择器)。因此,我们也将名称移动到属性中。
<ul>
<li data-name="Randy Hilpert">Randy Hilpert</li>
<li data-name="Peggie Jacobi">Peggie Jacobi</li>
<li data-name="Ethelyn Nolan Sr.">Ethelyn Nolan Sr.</li>
...
</ul>
现在要过滤包含“ rand”的名称的列表,非常简单:
li {
display: none;
}
li[data-name*="rand" i] {
display: list-item;
}
注意第5行的字母“i”。这表示“不区分大小写”,在这里非常有用。
为了使此动态化,我们将与input过滤器一起工作,我们需要使JavaScript不仅对键入的过滤器做出反应,而且还要生成与要搜索的内容匹配的CSS。
假设我们style在页面上有一个方块:
<style id="cssFilter">
/* dynamically generated CSS will be put in here */
</style>
我们可以监听过滤器输入的更改并生成该CSS:
filterElement.addEventListener("input", e => {
let filter = e.target.value;
let css = filter ? `
li {
display: none;
}
li[data-name*="${filter}" i] {
display: list-item;
}
` : ``;
window.cssFilter.innerHTML = css;
});
请注意,当过滤器为空时,我们将清空样式块,因此所有结果都会显示出来。
我承认利用CSS做到这一点很奇怪。
jQuery使得它更容易
既然我们仍然需要JavaScript,也许jQuery是可以接受的工具。这里有两个值得注意的变化:
- jQuery 可以根据项目包含的内容来选择项目。为此,它具有选择器API。我们不再需要多余的属性。
- 这将所有过滤保持在一种技术上。
我们仍然会监听输入内容的输入,然后,如果我们有过滤条件,我们将隐藏所有列表项,并显示包含过滤条件的项。否则,我们将再次显示所有内容:
const listItems = $("li");
$("#filter").on("input", function() {
let filter = $(this).val();
if (filter) {
listItems.hide();
$(`li:contains('${filter}')`).show();
} else {
listItems.show();
}
});
使过滤器不区分大小写比CSS更加费事,但是我们可以通过覆盖默认方法来做到这一点:
jQuery.expr[':'].contains = function(a, i, m) {
return jQuery(a).text().toUpperCase()
.indexOf(m[3].toUpperCase()) >= 0;
};
在React中可以使用状态跟Filter函数做到这一点
在React中没有做到这一点的真正方法,但我认为将名称列表保留为数据(如Array),映射它们并仅呈现所需内容是React-y。输入中的更改会过滤数据本身,并在需要时重新渲染React。
如果有一个names = [array, of, names],我们可以很容易地对其进行过滤:
filteredNames = names.filter(name => {
return name.includes(filter);
});
这次,可以这样区分大小写:
filteredNames = names.filter(name => {
return name.toUpperCase().includes(filter.toUpperCase());
});
然后,我们将执行.map()JSX中的典型操作来遍历数组并输出名称。
我没有任何特别的偏好
这不是您选择技术的目的。您可以使用现有技术进行操作。我也不认为任何一种方法在技术债务方面都比其他方法特别重。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。