jQuery按多个参数过滤问题

时间:2018-12-05 19:19:40

标签: javascript jquery json d3.js leaflet

位于下面的我的应用程序的目标是基于场景。如果我在类别中单击“韩语”,并且希望查看所有获得4星评分的内容,则结果应根据该查询进行简化。

现在,我遇到一个问题,可以按星级或类别进行过滤,但不能同时进行过滤。当我同时过滤时,所有结果都消失了。

可以在此处找到示例(很多东西不起作用):https://final-630-bthukxpnol.now.sh/

我的问题是为什么会这样?有没有其他方法可以过滤我未使用的内容?

如果不清楚,请要求我提供更多信息。

JS:

$('#star-filter, #cat-filter').delegate('input[type=checkbox]', 'change', function() {
        // $('input.star').not(this).prop('checked', false);  
        var $list = $('.leaflet-zoom-animated > g > circle'),
        $checked = $('input:checked');  
        if ($checked.length) {                          
            var sel = '';
            var catsel = '';
            var selector = '';

            $($checked).each(function(index, element){
                sel += "[data-staralt~='" + element.name + "']";  
                catsel += "[data-cat~='" + element.value + "']"; 
                selector += "[data-star~='" + element.value + "']";   
            });                        
            $list.hide();
            $('.leaflet-zoom-animated > g > circle').filter(sel).show();
            $('.leaflet-zoom-animated > g > circle').filter(catsel).show(); 
            $('.leaflet-zoom-animated > g > circle').filter(selector).show();

        }
        else {
            $list.show();
        }
    });

我正在使用D3.js和leaflet.js。

1 个答案:

答案 0 :(得分:1)

同时选中两者时,不保留任何匹配项的原因是,您生成了包含矛盾条件的过滤器。例如,它将生成3个这样的选择器:

[data-staralt~='4.5'][data-staralt~='category']
[data-cat~='4'][data-cat~='Ramen']
[data-star~='4'][data-star~='Ramen']

每个人都说该属性应同时包含两个词。这不是你所追求的。相反,我认为您想执行此逻辑(使用伪语言):

([data-staralt~='4.5'] or [data-cat~='4'] or [data-star~='4']) AND
([data-staralt~='category'] or [data-cat~='Ramen'] or [data-star~='Ramen'])

您可以使用以下代码来实现。旁注:不要使用不推荐使用的delegate jQuery方法,而是使用on方法(其前两个参数颠倒了):

$(document).on('change', 'input[type=checkbox]', function() {
    var $list = $('.leaflet-zoom-animated > g > circle'),
        $checked = $('input:checked');  
    if ($checked.length) {                          
        $list.hide();
        $($checked).each(function(index, element){
            // Reduce list to what matches one of the three filters.
            // The comma in the selector works as a logical OR:
            $list = $list.filter("[data-staralt~='" + element.name + "'],[data-cat~='" + element.value + "'],[data-star~='" + element.value + "']");
        });
    }
    // Show what remains in list:
    $list.show();
});

附录

转换后,我觉得您需要以下逻辑:

([data-staralt~='4.5'] or [data-staralt~='3.5']) and 
([data-cat~='4'] or [data-cat~='3']) and 
([data-star~='4'] and [data-star~='3])

我也开始理解staralt的原因,即当选择3时也包含3.5。但这可以通过^=比较来完成。因此,我会这样做,而不是执行额外的name属性检查。

因此导致以下代码:

function createFilter(type) { // Helper function
    var filter = [];
    $("#" + type + '-filter input:checked').each(function(index, element) {
        filter.push("[data-" + type + "^='" + element.value + "']"); // Use ^= to match the start of the actual value
    });
    return filter.join(",") || "*"; // Asterisk means: no filter at all
}

$(document).on('change', 'input[type=checkbox]', function() {
    $('.leaflet-zoom-animated > g > circle')
        .hide()
        .filter(createFilter("star")) // Any of the checked star selections, AND
        .filter(createFilter("review")) // Any of the review selections, AND
        .filter(createFilter("cat")) // Any of the cat selections
        .show(); // Show the matches of the above filter
});