Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 构建复选框过滤器以基于多个data-*属性显示/隐藏元素的最佳方法_Javascript_Jquery_Checkbox_Filter_Filtering - Fatal编程技术网

Javascript 构建复选框过滤器以基于多个data-*属性显示/隐藏元素的最佳方法

Javascript 构建复选框过滤器以基于多个data-*属性显示/隐藏元素的最佳方法,javascript,jquery,checkbox,filter,filtering,Javascript,Jquery,Checkbox,Filter,Filtering,我正在尝试构建一个复选框过滤器,它将根据元素上的多个data-*属性显示/隐藏元素。我做了几次尝试,但都没有达到我想要的过滤效果 我在以下方面做了大量工作: 我知道这个代码是不正确的,我只是在这里碰到了同样的墙,从头开始在小提琴 我想要的过滤是一个“和”过滤,你应用的过滤越多,你通常得到的结果就越少 例如,在小提琴中,如果你选择“gold”,你只会得到gold结果。如果你加上“银”过滤器,你会得到金和银,这到目前为止还不错。所以我在一个data-*属性内运行良好 问题是,如果您添加另一个dat

我正在尝试构建一个复选框过滤器,它将根据元素上的多个data-*属性显示/隐藏元素。我做了几次尝试,但都没有达到我想要的过滤效果

我在以下方面做了大量工作:

我知道这个代码是不正确的,我只是在这里碰到了同样的墙,从头开始在小提琴

我想要的过滤是一个“和”过滤,你应用的过滤越多,你通常得到的结果就越少

例如,在小提琴中,如果你选择“gold”,你只会得到gold结果。如果你加上“银”过滤器,你会得到金和银,这到目前为止还不错。所以我在一个data-*属性内运行良好

问题是,如果您添加另一个data-*过滤器,例如,在选择了gold和silver的情况下,添加“network A”过滤器。在这种情况下,我希望将结果过滤到黄金和白银元素,其中黄金/白银元素也具有网络A数据属性


构建这种过滤的最佳方法是什么,这样当应用价格过滤器时,它会过滤更多的结果?

下面是一个基本的shell,介绍您将要做的事情

$('input[type="checkbox"]').click(function() {
    var $checked = $('input[type="checkbox"]:checked');
    var $items = $('.productItem');
    var filters = {};

    if ($checked.length) {
        $('.productItem').hide();

        $checked.each(function() {
           filters[$(this).data('filter-type')] = $(this).val();
        });

        $items.each(function(i) {
            for (var key in filters) {
                if ($(this).data(key) == filters[key]) {
                    $(this).show();
                }
            }
        });
    } else {
        $('.productItem').show();
    }
});
让我看看能否用一种简单的方式来解释这一点。您试图完成的基本上是将过滤器映射到产品列表。对于每个过滤器,仅显示与过滤器匹配的产品。为了实现这一点,我将过滤器存储为键/值对。过滤器的关键是过滤器类型(级别、价格或网络),为了存储过滤器类型,我在每个复选框中添加了一个数据属性,
data filter type
。因此,对于筛选类型为level的复选框,属性将是
data filter type=“level”
。与现有的
value
属性相结合,过滤器可以在JavaScript中整齐地表示为键/值对:

data-filter-type: value
因此,当用户选择过滤器“白金”和“网络A”时,过滤器关联数组如下所示:

{
    level: platinum,
    network: networkA
}
现在,可以在过滤器数组中运行一个基本循环,并将包含其中任何一个过滤器的所有项作为目标。由于您的问题不够清晰,我假设您想要一个
关系,这意味着只有一个过滤器需要应用于该项目。如果需要将所有选定的过滤器应用于每个项目,则需要相应地修改代码

此代码的另一个问题是将筛选器添加到筛选器数组时:

filters[$(this).data('filter-type')] = $(this).val();
只有当每个过滤器都是唯一的,也就是说,每个过滤器中只有一个被选中时,这才起作用。例如,如果选中了两级过滤器,则只有第二级过滤器将应用,因为该键将被覆盖。您需要修改该零件以将两个值存储在同一个键下。每个键的基本值数组就可以完成这项工作

正如我所说,这是一个最小的例子。肯定会有更多的情况需要解决,但我概述的一般步骤是一个很好的起点。祝你好运


差点忘了小提琴链接

我认为,在应用后续条件之前,您需要在复选框中添加一个额外属性,以明确定义$productItem的顶级过滤器。我还改变了你的用户界面。隐藏过滤过的卡片对你的最终用户来说似乎是一种惩罚,所以灰显卡片(带有CSS不透明样式)看起来更流畅,但也许这只是我

<input type="checkbox" data-type="level" value="platinum" /> ...
<input type="checkbox" data-type="price" value="0-2" /> ...
<input type="checkbox" data-type="network" value="networkA" /> ...

请看这里的小提琴:

请你将你的问题添加到相关的html中,好吗?我不确定我是否完全理解你的目标,但如果它有帮助的话;你知道你可以在一个元素上链接选择器,对吗?例如,
$('.productItem[data level=3][data price=4].activeProductItem:focus:last child[data network=att]')
。如果没有空格,阅读起来会很困难,但实际上,你可以对单个元素应用许多选择器,无论它们是同一类型的还是其他类型的。我在这里放置任何代码的唯一原因是stackoverflow通过任何fiddle链接强制执行此操作。当fiddle以可执行格式保存所有代码时,在这里复制所有代码似乎是愚蠢的。拥有超过200的声誉(如我所写),您应该对该网站足够熟悉,了解我们要求将代码发布在这里,以便在(或如果)外部网站出现故障、死亡、重组或您自己删除fiddle时,这个问题仍然可以理解,并与未来的游客相关。如果没有其他原因,缺少“”代码会使您的问题“脱离主题”。不过,筛选并不是基于级别。例如,您应该能够在任何地方开始过滤,比如最初检查网络C,并将结果过滤到仅显示网络C。然后添加另一个过滤器,并进一步细化结果,以仅显示网络C和其他过滤器,好吗。做你想做的事情其实并不难(我想,如果我正确理解你的需求的话)。通过向所有复选框添加“数据类型”属性,然后创建多属性筛选器,您可以根据级联条件约束和筛选…我已更新了上面的答案。这很接近,但每个筛选器类别/方面/行中的复选框的作用类似于单选按钮。例如,如果您选中金和银,您应该获得所有装饰有金和银属性的卡。如果你再添加一个$0-2000的过滤器,你应该被过滤到所有的金0-2卡和银0-2卡。不过,在每个过滤器类别/方面/行中选择一个过滤器(最大值)看起来效果很好。现在我们开始讨论可用性问题,以及我所说的“相互排他性悖论”。我建议创建一个更好的UI,明确提示用户使用常识决策树(先选择级别,然后选择…),或者使用不透明度来灰显不符合规则的选择
<input type="checkbox" data-type="level" value="platinum" /> ...
<input type="checkbox" data-type="price" value="0-2" /> ...
<input type="checkbox" data-type="network" value="networkA" /> ...
$('input[type="checkbox"]').click(function() {
    var $checked = $('input[type="checkbox"]:checked');
    var $productItem = $('.productItem');
    var filters = [];
    var productFilter = '';

    if ($checked.length > 0) {
        $productItem.css('opacity',0.25);

        $checked.each(function() {
           dataType = $(this).attr('data-type');
           if (!filters[dataType]) filters[dataType] = [];  
           filters[dataType].push(this.value);
        });

        for(var filterType in filters) { 
            for (i in filters[filterType]) {
                productFilter += '[data-'+filterType+'="'+filters[filterType][i]+'"],';
            }
            productFilter = productFilter.replace(/,$/,'');
        }
        $productItem
            .filter(productFilter)
            .map(function() {
                $(this).css('opacity',1);
            });
    } else {
        $productItem.css('opacity',1);
    }
});