代码之家  ›  专栏  ›  技术社区  ›  brooksrelyt Ozal Zarbaliyev

jQuery多参数过滤问题

  •  0
  • brooksrelyt Ozal Zarbaliyev  · 技术社区  · 7 年前

    下面我的应用程序的目标是基于场景的。如果我单击类别中的韩语,并且希望看到所有级别为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和传单.js。

    1 回复  |  直到 7 年前
        1
  •  1
  •   trincot    7 年前

    当您同时检查两个选项时,没有匹配项的原因是您生成了包含矛盾条件的过滤器。例如,它将生成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
    });