按数据属性数组过滤jquery对象

时间:2017-06-01 19:52:20

标签: javascript jquery arrays custom-data-attribute

是否有更简单,更好或更简洁的方法来过滤使用包含数组的数据属性的元素列表?

目前,我们有一个很大的项目列表,每个项目包含一个存储在“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; }
        });                    
    });
});

4 个答案:

答案 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值键入你的元素,例如:

&#13;
&#13;
$(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;
&#13;
&#13;

势在必行

由于功能创建哈希的方法可能看起来令人困惑,我在这里提供命令式替代方案。但结果哈希对象将完全相同:

&#13;
&#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;
&#13;
&#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()
相关问题