【问题标题】:jQuery filter items by multiple attributes and with rangejQuery通过多个属性和范围过滤项目
【发布时间】:2021-03-21 16:19:13
【问题描述】:

好的,我一直在思考这个问题太久了,我似乎无法在这里找到解决方案,因为我的情况与 SO 上的其他问题有点不同。

我正在使用两个带有复选框的“过滤器”,用户可以选中这些复选框来查看某些项目(并隐藏与这些过滤器不匹配的其他项目)。

以下 html 代码包含过滤器:

<div class="filters">
    <p>Sex</p>
    <label><input name="sex" type="checkbox" value="Male">Male</label>
    <label><input name="sex" type="checkbox" value="Female">Female</label>
    <p>Age</p>
    <label><input name="age" value="0-17" type="checkbox">- 18j</label>
    <label><input name="age" value="18-24" type="checkbox">18j - 24j</label>
    <label><input name="age" value="25-34" type="checkbox">25j - 34j</label>
    <label><input name="age" value="35-55" type="checkbox"><35j - 55j</label>
    <label><input name="age" value="56-100" type="checkbox">55j +</label>
    <a id="filter">Filter items</a>
</div> 

项目设置如下,具有过滤器需要使用的适当数据属性:

<div class="items">
    <div class="item" data-sex="Male" data-age="22">
        Male / 22yo
    </div>
    <div class="item" data-sex="Female" data-age="35">
        Female / 35yo
    </div>
    <div class="item" data-sex="Male" data-age="17">
        Male / 17yo
    </div>
</div>

现在,过滤项目以将性别过滤器与数据属性完全匹配是相当简单的,我能够在其他一些问题的答案中找到一个可行的解决方案。但是,棘手的部分是年龄过滤器值包含一个范围(具有最小和最大年龄),我不知道如何设置过滤器,因此它考虑了所有过滤器,并且只显示那些满足每个约束的项目.

重要的是,如果同时检查了两性,则应仅考虑年龄过滤器,因为不存在同时满足两性的项目。但是如果只选择了男性,那么应该只返回带有 data-sex="Male" 的项目,如果这些项目被选中,它们也符合年龄过滤器。

下面的代码是我的jQuery代码,但我不知道如何包含年龄过滤器。选中的过滤器已正确添加到数组(sexes[]ages[]),我可以检查项目数据针对这些性别的数组进行属性,但我不知道如何在年龄范围内做到这一点..

$('body').on('click','#filter',function(event) { 
    event.preventDefault();
    
    $('.items .item').fadeOut(); // hide all items first
    
    var sexes = [];
    var ages = [];

    $('.filters input[name="sex"]').each(function(){
        if($(this).is(':checked')){
           sexes.push($(this).val());
        }
    });
    $('.filters input[name="age"]').each(function(){
        if($(this).is(':checked')){
           ages.push($(this).val());
        }
    });

    console.log(sexes);
    console.log(ages);

    $('.items .item').each(function() {
        if((sexes.indexOf($(this).data('sex')) > -1)) {
            $(this).fadeIn();
        }
        //how to include the ages filters here..?
    })

});

提前致谢!

【问题讨论】:

  • -上拆分,转换为实际数字,与.data("age")比较
  • oldest living person right now is 117。您可能需要调整设置以将她也包括在内。
  • 嗨@Andreas,谢谢,这也是我想到的方法。将尝试实施那个。谢谢你的提醒哈哈,但这是一个私人教练的网站,显示客户的前后照片,所以我认为我需要的不会超过 100 :)

标签: jquery custom-data-attribute


【解决方案1】:

要按年龄范围过滤,您需要用连字符将年龄分开,然后将左右两侧的数字与当前项目的年龄进行比较。因此,如果最小年龄和最大年龄在当前年龄范围内,则为真。

接下来,有一些方法可以优化您的 jQuery,这样您就不需要太多代码来收集选中的项目了。您也可以通过不使用.on('click','#filter',function()... 来摆脱event.preventDefault();。而是直接针对复选框。

如果您执行所有这些操作,那么您将获得此代码。我添加了 cmets 以帮助您了解发生了什么。

// create a click listener on all input checkboxes
$('input[type="checkbox"]').click(function() {
  // gets all the checked sexes in an array
  var sexes = $('input[name="sex"]:checked').get().map(function(item) {return item.value});
  // gets all the checked ages in an array
  var ages = $('input[name="age"]:checked').get().map(function(item) {return item.value;});
  // loop through each item
  $('.items .item').each(function() {
    // shorten the reference to the current item
    var item = $(this);
    // returns boolean; if no sexes where selected, true; else check if the current item sex exists in the selected sexes
    var has_matching_sex = !sexes.length || sexes.indexOf(item.attr('data-sex')) > -1;
    // returns boolean; if no ages where selected, true; else check if the current item age exists in the selected ages
    var has_matching_age = !ages.length || ages.some(function(age_range) {
      // breaks the ages into an array and age to into a number. ex: "18-24" to [18, 24]
      age_range = age_range.split('-').map(function(age) {return Number(age);});
      // converts current item age into a number so it can be easily compared to the age ranges
      var age = Number(item.attr('data-age'));
      // checks if current age is greater than or equal to minimum age of age range.
      var is_min_age_match = age >= age_range[0];
      // checks if current age is less than or equal to maximum age of age range.
      var is_max_age_match = age <= age_range[1];
      // if both previous booleans are true, return true, else false
      return is_min_age_match && is_max_age_match;
    });
    // if both sex and age match
    if (has_matching_sex && has_matching_age) {
      // show the item
      item.css('display', 'block');
    }
    // se or age did not match
    else {
      // hides the item
      item.css('display', 'none');
    }
  });
});

jsFidde:https://jsfiddle.net/35s84vLo/1/

【讨论】:

    猜你喜欢
    • 2011-10-21
    • 1970-01-01
    • 2011-08-27
    • 2020-01-20
    • 2011-02-05
    • 2014-09-10
    • 2021-09-23
    • 2018-05-13
    • 2023-03-12
    相关资源
    最近更新 更多