我目前有一个包含多个项目的网站。它们都是单独的div项目。它们都有一个与其他几个类名相同的类名作为标签,以帮助分隔它们(某些标签在多个div项中很常见)
我已经设置了使用data-filter =“。exampleclass”和data-filter =“。exampleclass2”等的按钮,这些按钮非常适合根据类名进行排序。我现在正在尝试创建一个搜索栏,用户可以在其中输入类名称,这样我就不必为所有按钮都做按钮。
document.getElementById("boxsearch").oninput = function() {
var matcher = new RegExp(document.getElementById("boxsearch").value, "gi");
for (var i = 0; i < document.getElementsByClassName("portfolio-item").length; i++) {
if (matcher.test(document.getElementsByClassName("category")[i])) {
document.getElementsByClassName("portfolio-item")[i].style.display = "inline-block";
} else {
document.getElementsByClassName("portfolio-item")[i].style.display = "none";
}
}
}
我没有包含jquery文件,因此按钮不起作用(它们在我端起作用),我只是不知道如何使用搜索栏搜索类名。
这是我所能找到的最接近的结果:http://jsfiddle.net/mttgj1tt/5/
答案 0 :(得分:0)
基于正则表达式匹配具有其类名之一的元素进行过滤是一种无效的方法。通常,您会建立索引并将其与更优化的搜索算法结合使用。
您可以使用一个类来选择目标元素集,然后遍历它们并获取其classList,然后遍历那些寻找匹配项的对象,以下是一个示例。但这还将测试与过滤或排序无关的其他类名称(例如,在下面的示例中,“框”仅用于显示,但元素仍然被过滤)。
一个更好的主意可能是将过滤器和排序值添加为数据属性,然后可以将它们与其他副作用区分开。我还建议建立一个主题元素索引,以便您可以先找到想要的元素,然后将其隐藏。
多个 getElementByClassName 调用既昂贵又不必要(尤其是在for循环中)。该示例对每个键盘调用一次。
function filterOnClass(baseClass, s) {
let re = new RegExp(s.trim(), 'i');
document.querySelectorAll('.' + baseClass).forEach(node => {
let cNames = Array.from(node.classList);
// Show all if search string is blank
if (s.trim() == '') {
node.classList.remove('hide');
// Otherwise, filter
} else if (cNames.some(cName => re.test(cName))) {
node.classList.add('hide');
} else {
node.classList.remove('hide');
}
});
}
.box {
height: 50px;
width: 100px;
border: 1px solid blue;
}
.hide {
display: none;
}
<input id="searchInput" onkeyup="filterOnClass('box', this.value)"><br>
<div class="box foo">foo</div>
<div class="box foo bar">foo bar</div>
<div class="box fum bar">fum bar</div>
<div class="box fum">fum</div>