javascript - 按数据属性中匹配的关键字对列表进行排序
问题描述
我有一长串基本的 JavaScript 搜索。搜索功能使用正则表达式来测试是否满足某些条件,并隐藏不满足的条件。我正在尝试对列表进行排序并优先考虑在属性 1 中找到的那些,然后是在属性 2 中匹配关键字的项目。场景描述如下。
我的列表
- 巧克力焦糖
- 大蒜蛋黄酱
- 番茄鸡蛋
- 炒鸡蛋
目前-当我搜索时egg
,它返回如下列表
- 大蒜蛋黄酱
- 番茄鸡蛋
- 炒鸡蛋
Aiming for -这是我正在寻找的结果
- 炒鸡蛋
- 番茄鸡蛋
- 大蒜蛋黄酱
从列表中我们可以看到,它的产品标题Garlic Mayonnaise
中没有,但是搜索返回true,因为在data属性中找到,如下图所示。Egg
egg
<li productname="Garlic Mayonnaise" data-desc="Contains egg">Garlic Mayonnaise</li>
有什么方法可以按在标题中找到的关键字对列表进行排序,然后是在数据属性中找到的那些关键字?
我的搜索功能如下
let productList = $('#productListUL li');
$.each(productList, function(_index, product){
let self = $(product),
productId = self.attr('productid'),
productName = self.attr('productname'),
productDesc = self.attr('data-desc');
if (
regex.test(productId) ||
regex.test(productName) ||
regex.test(productDesc)
)
{
self.removeClass('hidden');
}
else{
self.addClass('hidden');
}
});
解决方案
您可以简单地使用操作顺序。这意味着在列表中通过两次,它会给你你想要的结果。
$(function() {
function sortList(d, lObj) {
var c = [];
$.each(d, function(k, p) {
c.push($("li", lObj).eq(p.index).detach());
});
lObj.append(c);
}
function filterList(q, lObj, s) {
q = q.toLowerCase();
// Optional perimeter
if (s == undefined) {
s = false;
}
// Get List Items
var ls = lObj.children();
// Hide them all
ls.addClass("hidden");
// Array for Filtered/Sorted results
var results = [];
// First Pass, Filter by Name
ls.each(function(i, p) {
if ($(p).data("name").toLowerCase().indexOf(q) > -1) {
results.push({
index: $(p).index(),
name: $(p).data("name"),
desc: $(p).data("desc"),
});
$(p).removeClass("hidden");
}
});
console.log("P1", results);
// Second Pass, filter by Desc
// Skip any already unfiltered
ls.each(function(i, p) {
if ($(p).hasClass("hidden") && $(p).data("desc").toLowerCase().indexOf(q) > -1) {
results.push({
index: $(p).index(),
name: $(p).data("name"),
desc: $(p).data("desc"),
});
$(p).removeClass("hidden");
}
});
console.log("P2", results);
// Array is built with desired filter and sort due to order of operations
// Check if Element Sort is required
if (s) {
sortList(results, lObj);
}
// Return Filtered/Sorted Array
return results;
}
$(".filter").keyup(function() {
$(".hidden").removeClass("hidden");
if ($(this).val().length > 2) {
filterList($(this).val(), $(".productList"), true);
}
});
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Search: <input type="text" class="filter">
<ul class="productList">
<li data-name="Chocolate Caramels" data-desc="Contains dairy">Chocolate Caramels</li>
<li data-name="Garlic Mayonnaise" data-desc="Contains egg">Garlic Mayonnaise</li>
<li data-name="Tomato Egg" data-desc="Contains egg">Tomato Egg</li>
<li data-name="Scrambled egg" data-desc="Contains egg">Scrambled egg</li>
</ul>
过滤本身不会对列表中的元素进行排序,因此请根据我们构建的数组创建另一个函数来执行此操作。这会将它们分离并将它们按顺序放置在列表的末尾,并且所有其他项目都被隐藏。
推荐阅读
- sql - 如何使用多个过滤器将记录提取到数组
- mysql - 使用 mysql 语句插入图像后,我的照片字段在我的表结构中仍然显示为空
- javascript - 为什么酶“安装”包装只是呈现
- 标签,但没有别的?
- java - 如何删除另一个线程正在使用的文件?
- php - 为什么这段代码在数据库中不起作用?
- math - 找到两个长度之间的交点
- java - 即使没有添加任何内容,我是否应该在子类中覆盖 equals 和 hashCode?
- node.js - 包括来自其他视图文件夹的 pug mixin
- reactjs - this.setState 不适用于我的 React 本机项目
- powerpoint - 在多张幻灯片上销毁图像