如何根据多属性和多属性值显示/隐藏元素?

时间:2022-11-25 19:29:31

I would like to view/hide divs on a page, based on attribute filters. I've made several attributes which can have multiple values. Users can choose which ones they want to see displayed.

我想基于属性过滤器在页面上查看/隐藏div。我已经制作了几个可以有多个值的属性。用户可以选择要显示的内容。

I can't get the right algorythm (or I don't know which Javascript/jQuery function to use). The following obviously doesn't work. I'm first showing ALL items, and then loop through the filters, hiding the ones that don't match the attributes (read: the current attribute in the loop). This means items get hidden even though they might match an attribute later on...

我无法得到正确的algorythm(或者我不知道使用哪个Javascript / jQuery函数)。以下显然不起作用。我首先显示所有项目,然后遍历过滤器,隐藏那些与属性不匹配的项目(读取:循环中的当前属性)。这意味着项目会被隐藏,即使它们可能稍后匹配某个属性...

How can I make this filtermechanism work and don't exclude/hide items that needn't be hidden based on selected attributes later in the loop? Maybe there is some OR-operator I can use with attribute selecting ('div[group=firstgroup|thirdgroup]') ?

如何使这个filtermechanism工作,并且不排除/隐藏在循环后面根据所选属性不需要隐藏的项目?也许有一些OR运算符可以用于属性选择('div [group = firstgroup | thirdgroup]')?

Javascript:

    $(document).ready(function() {
        var items = $('#items').find('div');
        $(items).show();

        var groupsToShow = Array('firstgroup','thirdgroup');
        var namesToShow = Array('Fred','Pete');
        var applicationsToShow = Array('light');

        for(var i=0;i<groupsToShow;i++) {
            $(items).find('div[group!='+groupsToShow[i]+']').hide();    
        }

        for(var i=0;i<namesToShow;i++) {
            $(items).find('div[name!='+namesToShow[i]+']').hide();    
        }

        for(var i=0;i<applicationsToShow;i++) {
            $(items).find('div[application!='+applicationsToShow[i]+']').hide();    
        }
    });

HTML Code:

<div id="items">
    <div group="firstgroup" name="Rob" application="special"></div>
    <div group="firstgroup" name="Fred" application="light"></div>
    <div group="secondgroup" name="Pete" application="special"></div>
    <div group="thirdgroup" name="Pete" application="special"></div>
    <div group="thirdgroup" name="Pete" application="light"></div>
    <div group="secondgroup" name="Pete" application="normal"></div>
    <div group="thirdgroup" name="Pete" application="special"></div>
</div>

2 个解决方案

#1


As I understand it, you only want elements to be shown if they satisfy what's contained in all three arrays. So in the above situation the second and fifth DIVs would be the only ones showing... Is that correct?

据我了解,如果元素满足所有三个数组中包含的内容,则只需要显示元素。因此,在上述情况下,第二和第五个DIV将是唯一显示......这是正确的吗?

If my assumptions are correct then this should work:

如果我的假设是正确的那么这应该工作:

var show = {
    'group': ['firstgroup','thirdgroup'],
    'name': ['Fred','Pete'],
    'application': ['light']
};

$('#items div')
    .hide()
    .filter(function(){
        // Only returns true for elements
        // that satisfy all three arrays
        for (var i in show) {
            var attr = $(this).attr(i),
                match = ('|' + show[i].join('|') + '|').indexOf(attr) > -1;
            if (!match) {
                return false;
            }
        }
        // If we reach this point then we can assert
        // that the element contains all required attributes
        return true;
    })
    .show();

#2


You can build a list of items to show by using add():

您可以使用add()构建要显示的项目列表:

$(document).ready(function() {
    var items = $('#items').find('div');
    $(items).hide();

    var groupsToShow = ['firstgroup','thirdgroup'];
    var namesToShow = ['Fred','Pete'];
    var applicationsToShow = ['light'];

    var $itemsToShow = $();

    for(var i=0;i<groupsToShow;i++) {
        $itemsToShow = $itemsToShow.add('div[group='+groupsToShow[i]+']');
    }

    for(var i=0;i<namesToShow;i++) {
        $itemsToShow = $itemsToShow.add('div[name='+namesToShow[i]+']');    
    }

    for(var i=0;i<applicationsToShow;i++) {
        $itemsToShow = $itemsToShow.add(('div[application='+applicationsToShow[i]+']');    
    }

    $itemsToShow.show();
});

#1


As I understand it, you only want elements to be shown if they satisfy what's contained in all three arrays. So in the above situation the second and fifth DIVs would be the only ones showing... Is that correct?

据我了解,如果元素满足所有三个数组中包含的内容,则只需要显示元素。因此,在上述情况下,第二和第五个DIV将是唯一显示......这是正确的吗?

If my assumptions are correct then this should work:

如果我的假设是正确的那么这应该工作:

var show = {
    'group': ['firstgroup','thirdgroup'],
    'name': ['Fred','Pete'],
    'application': ['light']
};

$('#items div')
    .hide()
    .filter(function(){
        // Only returns true for elements
        // that satisfy all three arrays
        for (var i in show) {
            var attr = $(this).attr(i),
                match = ('|' + show[i].join('|') + '|').indexOf(attr) > -1;
            if (!match) {
                return false;
            }
        }
        // If we reach this point then we can assert
        // that the element contains all required attributes
        return true;
    })
    .show();

#2


You can build a list of items to show by using add():

您可以使用add()构建要显示的项目列表:

$(document).ready(function() {
    var items = $('#items').find('div');
    $(items).hide();

    var groupsToShow = ['firstgroup','thirdgroup'];
    var namesToShow = ['Fred','Pete'];
    var applicationsToShow = ['light'];

    var $itemsToShow = $();

    for(var i=0;i<groupsToShow;i++) {
        $itemsToShow = $itemsToShow.add('div[group='+groupsToShow[i]+']');
    }

    for(var i=0;i<namesToShow;i++) {
        $itemsToShow = $itemsToShow.add('div[name='+namesToShow[i]+']');    
    }

    for(var i=0;i<applicationsToShow;i++) {
        $itemsToShow = $itemsToShow.add(('div[application='+applicationsToShow[i]+']');    
    }

    $itemsToShow.show();
});