javascript - jQuery过滤多个数据属性
问题描述
我的网站上有一份待售汽车清单,以及五个过滤器:
- 制作
- 模型
- 年
- 里程
- 价格
...每个都有多个用户可以过滤的选项。
当用户检查过滤器列表中的一个或多个选项时,我需要隐藏与所有选定过滤器不匹配的汽车。
这是其中一辆车的 HTML:
<div class="home-car-div">
<div class="home-car-description-div">
<p class="home-car-info" data-year="2018" data-make="Ford" data-model="Escape" data-mileage="10000" data-price="18900">
2018 Ford Escape
</p>
</div>
</div>
这是过滤器之一:
<div class="car-filters">
<div class="make-section">
<p class="filter-title">Make</p>
<div id="makeSection" data-group="make">
<label class="filter-input">
<input type="checkbox" name="make" class="make" value=“Ford”>Ford
</label>
<label class="filter-input">
<input type="checkbox" name="make" class="make" value="Subaru"> Subaru
</label>
</div>
</div>
</div>
我在网站上关注了其他一些问题,我似乎已经完成了大部分工作。每当用户选中其中一个过滤器复选框时,我都会在键/值对数组中获取每个属性的所有值:
var $filterCheckboxes = $( '.filter-input input' );
$filterCheckboxes.on( 'change', function() {
$('.home-car-div').show();
var selectedFilters = {};
$filterCheckboxes.filter( ':checked' ).each( function() {
if ( ! selectedFilters.hasOwnProperty( this.name ) ) {
selectedFilters[ this.name ] = [];
}
selectedFilters[ this.name ].push( this.value );
});
$('.home-car-info').each(function() {
var carMake = $(this).data('make');
var carModel = $(this).data('model');
var carYear = $(this).data('year');
var carPrice = $(this).data('price');
var carMileage = $(this).data('mileage');
var filteredMake = selectedFilters.make;
var filteredModel = selectedFilters.model;
var filteredYear = selectedFilters.year;
var filteredPrice = selectedFilters.price;
var filteredMileage = selectedFilters.mileage;
});
});
所以现在我有每个汽车属性的变量,以及每个过滤选择的变量,但我现在需要比较每一个,并以某种方式隐藏不匹配所有属性的汽车。
如果没有结果,我也想显示一条消息。
我在正确的轨道上,我该如何进行过滤?
解决方案
我相信这与您所追求的很接近。我使用函数式编程对数据类别而不是单个元素执行操作。并不真正遵守此要求:“隐藏与所有属性不匹配的汽车”,因为该要求对于“制造”和“型号”等互斥属性没有意义。还删除了一些无关的类并在标签上使用了“for”属性(请参阅this)。
实现取决于假设如果没有选择该类别中的任何内容,则汽车与该类别匹配。
注意:JQuery 存在一个问题,导致它的.data()
方法在功能上与 DOM 的.dataset
属性不同,因此使用 ofthis.dataset[category]
代替$(this).data(category)
. 从技术上讲,这也应该是更好的性能,并且可以说也更具可读性。
$(function() {
$('#button').click(function() {
// Create an map of category name to selected filters
selectedFilters = $('.car-filters input:checked').get().reduce( function(a, c) { a[c.name] = (a[c.name] || []); a[c.name].push(c.value); return a }, {} )
// filter the list of cars displayed
match = 0
unmatchedCars = $('.home-car-info').filter(function() {
for (const category in selectedFilters) {
// must match at least one in each category
if (!selectedFilters[category].includes(this.dataset[category])) {
console.log(`"${$(this).text().trim()}" does not match ${category} is in [${selectedFilters[category]}] (${category} is ${this.dataset[category]})`)
return true
}
match++
}
});
// do something with unmatchedCars
unmatchedCars.hide()
if (!match) {
console.log("Nothing matches the selected filters")
}
})
$('#restore').click(function() {
$('.home-car-info').show()
$('input:checkbox').prop('checked', false)
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="home-car-div">
<div class="home-car-description-div">
<p class="home-car-info" data-year="2018" data-make="Ford" data-model="Escape" data-mileage="10000" data-price="18900">
2018 Ford Escape
</p>
<p class="home-car-info" data-year="1998" data-make="Porsche" data-model="911" data-mileage="10000" data-price="72500">
1998 Porsche 911
</p>
</div>
</div>
<form>
<div class="car-filters">
<div class="make-section">
<p >Make</p>
<div id="makeSection" data-group="make">
<input type="checkbox" id="iaa" name="make" value="Ford"><label for="iaa">Ford</label>
<input type="checkbox" id="iab" name="make" value="Subaru"><label for="iab">Subaru</label>
<input type="checkbox" id="iab" name="make" value="Porsche"><label for="iac">Porsche</label>
</div>
<p >Model</p>
<div id="makeSection" data-group="model">
<input type="checkbox" id="iba" name="model" value="T"><label for="iba">T</label>
<input type="checkbox" id="ibb" name="model" value="Escape"><label for="ibb">Escape</label>
<input type="checkbox" id="ibb" name="model" value="911"><label for="ibc">911</label>
</div>
</div>
</div>
<div>
<button id="button" type="button">Filter</button>
<button id="restore" type="button">Restore</button>
</div>
</form><br />
推荐阅读
- java - 从 Recycler View Button Click 更改不同的按钮文本
- node.js - 如何在 node js 中为 firebase 功能安装 ffmpeg
- javascript - 如何在 react-router 中正确键入组件道具?
- mysql - MySQL选择满足特定行条件的所有列名
- javascript - 如何用cheerio从两个相同的班级获得第一堂课
- node.js - Electron App中的Imagemin不压缩图像
- xpath - 无法获取强标签中的值
- java - 如何修复此 Android Firebase“客户端离线”错误
- azure - 自定义策略不尊重电子邮件操作模式
- python - 使用 python 从网站访问数据会产生不完整的网站数据