首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用jQuery过滤基于多个数据属性的列表项?

如何使用jQuery过滤基于多个数据属性的列表项?
EN

Stack Overflow用户
提问于 2016-06-25 23:44:50
回答 3查看 1.8K关注 0票数 3

下面是带有所有过滤器的HTML:

代码语言:javascript
复制
  <div class="search-filters">
    <div class="filter-block">
      <label for="employee_type">Employee Type</label>
      <select id="employee_type" class="category">
        <option value="0">All</option>
        <option value="designer">Designer</option>
        <option value="manager">Manager</option>
        <option value="developer">Developer</option>
        <option value="quality-assurance">Quality Assurance</option>
      </select>
    </div>
    <div class="filter-block">
      <label for="years_xp">Years Experience</label>
      <select id="years_xp" class="category">
        <option value="0">Select years Experience</option>
        <option value="1">1 year</option>
        <option value="2">2 years</option>
        <option value="3">3 years</option>
      </select>
    </div>

  </div>

我的结果清单如下:

代码语言:javascript
复制
 <ul class="result-set">
   <li class="result" data-employee-type="designer" data-xp="3" >John Smith</li>
   <li class="result" data-employee-type="manager" data-xp="2" >Billy Joe</li>
   <li class="result" data-employee-type="developer" data-xp="5" >John Appleseed</li>
 </ul>

因此,我要做的是使用jQuery使用数据属性过滤结果,并在更改时选择下拉。现在,只有一个或另一个过滤器与下面的jQuery代码一起工作。我尝试在Jquery中使用.filter函数,但只有在更改一个下拉列表时,它才能工作。如果我两者都改变了,那似乎就是忽略了一个条件。

我的jQuery:

代码语言:javascript
复制
var category_filters = [];

$('.category').on('change', function() {
    category_filters = [];

    $('.search-filters select').each(function() {
        if ($(this).val() != 0) {
            var category = $(this).val();
            category_filters[$(this).attr('id')] = category;
        }
    });

    var employee_type = "";
    var years_xp = "";

    if ('employee_type' in category_filters) {
        employee_type = category_filters['employee_type'];
    }
    if ('years_xp' in category_filters) {
        years_xp = category_filters['years_xp'];
    }

    $(".result-set .result").hide().filter(function() {
        if (employee_type != "") {
            if ($(this).attr('data-employee-type') == employee_type) {
                return true;
            }
        }
        if (years_xp != "") {
            if ($(this).attr('data-xp') == years_xp) {
                return true;
            }
        }
    }).show();

});

对我做错了什么有什么想法吗?我已经在这个问题上被困了将近6个小时,并且看过其他的例子,但它们似乎不适用于我的情况。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-26 00:37:33

好的,所以您希望两个过滤器同时应用,而不仅仅是在单个筛选器匹配时就显示一个项。在筛选函数中,一旦找到匹配项,就返回true,这就是问题所在。

我继续对您的代码做了一些更新:

代码语言:javascript
复制
$('.category').on('change', function() {
  var category_filters = [];

  $('.search-filters select').each(function() {
    if ($(this).val() != 0) {
      category_filters[$(this).attr('id')] = $(this).val();
    }
  });

  $(".result-set .result").hide().filter(function() { 
    var show = true;
    for (var category in category_filters) {
       show = show && $(this).data(category) == category_filters[category];
    }

    return show;
  }).show();

});

还有一个演示:https://jsfiddle.net/04v4bqw5/1/

正如您所注意到的,我也做了一些重构。此代码假定过滤器的id与要应用筛选器的数据属性的名称完全匹配,因此也要检查更新的HTML。

javascript的重复次数要少得多,您可以添加任意多的额外过滤器和匹配的数据属性,并且它们可以工作,而不必更改javascript。

至于过滤器函数,让我添加一些注释来解释。

代码语言:javascript
复制
// assume we'll want to show the item
var show = true;
// go over each active filter
for (var category in category_filters) {
   // check if the filter value matches the data attribute value, and any
   // previous filters did not exclude this item yet (show &&)
   show = show && $(this).data(category) == category_filters[category];
}

return show;
票数 2
EN

Stack Overflow用户

发布于 2016-06-26 00:27:06

你之所以得到这个结果,是因为return true;的行为。把这看作是一个中断语句--一旦在.filter函数中达到了这一点,它就会认为它在那里的工作已经完成,并且可以停止处理。要克服这一问题,请使用一些本地布尔值,然后在函数的末尾对它们进行评估,以决定是否返回true:

代码语言:javascript
复制
var etMatch = false, xpMatch = false;

if (employee_type != "") {
    if ($(this).attr('data-employee-type') == employee_type) {
        etMatch = true;
    }
}

if (years_xp != "") {
    if ($(this).attr('data-xp') == years_xp) {
        xpMatch = true;
    }
}

if (etMatch && xpMatch) { return true; }
票数 1
EN

Stack Overflow用户

发布于 2016-06-26 00:47:28

对于每个过滤器,您应该使用它的功能进行比较:

代码语言:javascript
复制
var compare = {
  "employee-type": function(a,b) { return a===b},
  "years-xp": function(a,b) { return (1*a)<=(1*b) }
}

$(".result-set .result").show().filter(function() {

  var self = this;

  return 
    !Object
     .keys(category_filters)
     .reduce( function(result, i) {

       var filterValue = category_filters[i];
       var itemValue = $(self).attr('data-'+i);

       return result && compare[ i ]( filterValue, itemValue)

     }, true)

}).hide();

[ https://jsfiddle.net/qqc9w4xm/ ]

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38033942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档