是否有更简单,更好或更简洁的方法来过滤使用包含数组的数据属性的元素列表?
目前,我们有一个很大的项目列表,每个项目包含一个存储在“data-tags”属性中的数组中的一个或多个标记,如下所示:
<div class="viewItem" data-tags='[{"id":1,"name":"Tag 01"},{"id":2,"name":"Tag 02"}]'></div>
<div class="viewItem" data-tags='[{"id":2,"name":"Tag 02"}]'></div>
<div class="viewItem" data-tags='[{"id":1,"name":"Tag 01"},{"id":3,"name":"Tag 03"}]'></div>
该对象仅显示data-tags数组中具有特定标记的div。下面的代码可以工作,但我觉得在处理大量项目时非常低效,并希望找到更好的答案,无论是使用jquery过滤器还是grep或其他东西。
$(function () {
//Instantiate variables
var $viewItems = $('.viewItem');
var filterId = 2;
//Hide all items in object array.
$viewItems.hide();
//Loop thru EACH item and show only those with matching id in array
$viewItems.each(function () {
var thisItem = $(this);
var array = thisItem.data("tags");
$.each(array, function (i, obj) {
if (obj.id == filterId) { thisItem.show(); return false; }
});
});
});
答案 0 :(得分:0)
您可以为每个标记创建css类。示例:tag-1,tag-2等。
将标记放在类部分中,如下所示:<div class="viewItem tag-1 tag2".../>
因此,您可以轻松选择/显示/隐藏任何标签组合,如下所示:
// Hide tag-1
$(".tag-1").css('display','none')
// Show tag-2
$(".tag-2").css('display','block');
// Select elements with tag-1 and tag-2
$(".tag-1 tag-2").css('background','pink');
答案 1 :(得分:0)
使用jQuery grep
函数过滤元素。然后在grep函数内部解析data-tags
属性并查找是否存在具有给定id的元素:
var filterId = 1;
var dataTags;
var arr = $.grep($('.viewItem'), function( el ) {
dataTags = JSON.parse($(el).attr('data-tags'));
return dataTags.find(el => el.id === filterId);
});
console.log(arr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="viewItem" data-tags='[{"id":1,"name":"Tag 01"},{"id":2,"name":"Tag 02"}]'></div>
<div class="viewItem" data-tags='[{"id":2,"name":"Tag 023"}]'></div>
<div class="viewItem" data-tags='[{"id":1,"name":"Tag 01"},{"id":3,"name":"Tag 03"}]'></div>
答案 2 :(得分:0)
首先,data
方法相当快:jQuery只在第一次访问时从DOM读取值,但随后将值(本例中的对象)保存在内存中,并且不会读取DOM的数据属性。
因此,如果这些JSON值不是很大,那么 id 对项目的过滤将不会占用大部分时间。最耗时的部分是您致电.hide()
和.show()
的地方,因为它涉及与DOM的互动和呈现。
但是,如果你真的需要优化它,你可以做一些预处理并通过这个JSON id值键入你的元素,例如:
$(function () {
// Pre-processing: key all viewItems by the id in their data-tags:
var hash = $('.viewItem').get().reduce(function (hash, div) {
return $(div).data("tags").reduce(function (hash, o) {
hash[o.id] = (hash[o.id] || []).concat(div);
return hash;
}, hash);
}, {});
// Actual filtering
$('#apply').click(function() {
var filterId = $('#filter').val();
$('.viewItem').hide();
$(hash[filterId]).show();
});
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Filter ID: <input id="filter"><button id="apply">Apply</button><br>
<div class="viewItem" data-tags='[{"id":1,"name":"Tag 01"},{"id":2,"name":"Tag 02"}]'>1,2</div>
<div class="viewItem" data-tags='[{"id":2,"name":"Tag 02"}]'>2</div>
<div class="viewItem" data-tags='[{"id":1,"name":"Tag 01"},{"id":3,"name":"Tag 03"}]'>1,3</div>
&#13;
由于功能创建哈希的方法可能看起来令人困惑,我在这里提供命令式替代方案。但结果哈希对象将完全相同:
$(function () {
// Pre-processing: key all viewItems by the id in their data-tags:
var hash = [];
$('.viewItem').each(function (i, div) {
$.each($(div).data("tags"), function (j, obj) {
if (!(obj.id in hash)) hash[obj.id] = [];
hash[obj.id].push(div);
});
});
// Actual filtering
$('#apply').click(function() {
var filterId = $('#filter').val();
$('.viewItem').hide();
$(hash[filterId]).show();
});
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Filter ID: <input id="filter"><button id="apply">Apply</button><br>
<div class="viewItem" data-tags='[{"id":1,"name":"Tag 01"},{"id":2,"name":"Tag 02"}]'>1,2</div>
<div class="viewItem" data-tags='[{"id":2,"name":"Tag 02"}]'>2</div>
<div class="viewItem" data-tags='[{"id":1,"name":"Tag 01"},{"id":3,"name":"Tag 03"}]'>1,3</div>
&#13;
答案 3 :(得分:0)
jQuery过滤器怎么样?
var $viewItems = $('.viewItem');
var filterId = 2;
//Hide all items in object array.
$viewItems.hide();
//Loop thru EACH item and show only those with matching id in array
$viewItems.filter(function (i, el) {
var dataTags = $(el).data("tags");
return dataTags.filter(tag => tag.id === filterId).length
}).show()