我正在尝试根据数据属性过滤结果。在大多数情况下,我认为我在那里(它在前3个选择器上有效),但我在试图将日期选择器带入等式时遇到了麻烦。在这一点上,我的问题是我的方法是完全正确的-如果需要的话,我可以改变HTML -所以请随时提供一个更好的解决方案。
为了方便任何愿意提供帮助的人,这里有个小提琴:https://jsfiddle.net/rnbx0c3j/
谢谢
选择器:
<div id="stats_filter">
<div id="stats_filter_wrapper" class="grids">
<div class="grid-3 select-wrapper server first">
<label class="server">Server</label>
<select id="select-server">
<option value="all">All</option>
<option value="NicNicFunGame">NicNicFunGame</option>
<option value="GT3_races">GT3_races</option>
</select>
</div>
<div class="grid-3 select-wrapper track">
<label class="track">Track</label>
<select id="select-track">
<option value="all">All</option>
<option value="ks_brands_hatch">ks_brands_hatch</option>
<option value="Imola">Imola</option>
<option value="Spa">Spa</option>
</select>
</div>
<div class="grid-3 select-wrapper car">
<label class="car">Car</label>
<select id="select-car">
<option value="all">All</option>
<option value="ariel_atom_v8">ariel_atom_v8</option>
<option value="rr_caterham_academy_620r">rr_caterham_academy_620r</option>
<option value="ks_porsche_911_gt1">ks_porsche_911_gt1</option>
</select>
</div>
<div class="grid-3 select-wrapper date">
<label class="date">Date</label>
<select id="select-date">
<option value="all">All</option>
<option value="7">Last 7 days</option>
<option value="30">Last 30 days</option>
<option value="182">Last 6 months</option>
<option value="365">Last 12 months</option>
</select>
</div>
</div>
</div>要过滤的HTML
<div class="stats-section" id="sectionID_1" data-server="NicNicFunGame" data-track="ks_brands_hatch" data-date="27/09/2019" data-car="ariel_atom_v8">sectionID_1</div>
<div class="stats-section" id="sectionID_2" data-server="NicNicFunGame" data-track="Imola" data-date="03/07/2019" data-car="rr_caterham_academy_620r">sectionID_2</div>
<div class="stats-section" id="sectionID_3" data-server="GT3_races" data-track="Spa" data-date="14/01/2019" data-car="ariel_atom_v8, ks_porsche_911_gt1">sectionID_3</div>JS
var $select = $('#stats_filter select');
var $statsSection = $('.stats-section');
$select.change(function () {
var include = '';
var exclude = [];
var showAll = true;
var filterDate = false;
$select.each(function () {
var val = $(this).children(':selected').val();
if (val !== 'all') {
switch ($(this).prop('id')) {
case 'select-server':
include += "[data-server='" + val + "']";
break;
case 'select-track':
include += "[data-track='" + val + "']";
break;
case 'select-car':
include += "[data-car*='" + val + "']";
break;
case 'select-date':
var selectedDate = new Date(new Date().setDate(new Date().getDate() - val));
var dd = selectedDate.getDate();
var mm = selectedDate.getMonth() + 1;
var yyyy = selectedDate.getFullYear();
if (dd < 10) {
dd = '0' + dd;
}
if (mm < 10) {
mm = '0' + mm;
}
selectedDate = dd + '/' + mm + '/' + yyyy;
//exclude when date is out of range
$statsSection.each(function () {
var sectionDate = $(this).data('date');
if (process(sectionDate) < process(selectedDate)) {
exclude.push("[data-date='" + sectionDate + "']");
}
exclude.join(',');
});
function process(date) {
var parts = date.split("/");
return new Date(parts[2], parts[1] - 1, parts[0]);
}
filterDate = true;
break;
}
showAll = false;
}
});
if (showAll) {
$statsSection.show();
} else {
//HOW TO DEAL WITH THE DATES??
if (filterDate == true) {
alert('the following dates should be excluded from the results: ' + exclude);
}
//this works for the non-date selectors
$statsSection.not($(include)).hide();
$statsSection.filter($(include)).show();
}
});发布于 2019-10-02 18:28:06
因此,对于非日期项,您的技术是计算应该包含的元素的jquery选择器,然后将其应用于数据div。
这是一种非常好的方法,因为在构建'include‘变量时,您可以构建多个jquery过滤器。
对日期应用相同技术的困难在于,这会产生一个范围测试,该范围测试很难放入jquery选择器中。我的解决方案是构造一个符合条件的数据-日期值的数组,并在最后一步中执行第二个过滤器。
这些更改包括:
步骤1.定义一个新变量:
var dateInclude = [];步骤2.在确定日期是否有效的部分中,将有效值推入dataInclude过滤器数组
//exclude when date is out of range
$statsSection.each(function () {
var sectionDate = $(this).data('date');
if (process(sectionDate) > process(selectedDate)) {
dateInclude.push("[data-date='" + sectionDate + "']");
}
});步骤3:在输出部分中,我们现在将dateInclude组合为第二个过滤器。注意,您的初始筛选器作为布尔AND操作,但是日期筛选器必须作为布尔OR操作,因此dateInclude筛选器作为第二步应用于show()操作。
$statsSection.hide();
include = (dateInclude.length > 0 && include === '' ? '*' : include);
dateInclude = (dateInclude.length === 0 ? ['*'] : dateInclude );
$('#info').html(include + ' :: ' + dateInclude.join());
$statsSection.filter(include).filter(dateInclude.join()).show();第一行(下面)先发制人地隐藏了所有数据。
$statsSection.hide();接下来的几行(下面)对过滤器进行操作,以确保它们都有一个值。如果不存在日期筛选器,我们将为其他选择框的“包含”筛选器注入一个“全部匹配”筛选器。
include = (dateInclude.length > 0 && include === '' ? '*' : include);
dateInclude = (dateInclude.length === 0 ? ['*'] : dateInclude );最后,我们将这些放在一起,如下所示。
$statsSection.filter(include).filter(dateInclude.join()).show();为了帮助可视化,我在小提琴中添加了一些输出
例如,选择六个月的server=NicNicFunGame和date=last将生成过滤器:
$statsSection.filter("[data-server='NicNicFunGame']").filter("[data-date='27/09/2019'],[data-date='03/07/2019']").show();发布于 2019-10-02 17:51:49
您可以将所有stats-section存储到对象数组中,并使用array filter进行搜索
var t0 = performance.now();
var initialized = false;
var $select = $('#stats_filter select');
function initialize() {
mySelectors = [];
$statsSection = $('.stats-section');
console.log("First search will be costly");
$($statsSection).each(function (i, e) {
let temp = $(e).data();
temp.element = $(e);
let myDate = temp.date.split("/");
temp.date = new Date(myDate[1] + "/" + myDate[0] + "/" + myDate[2]).getTime();//fix date format and convert to timestamp
mySelectors.push(temp);
});
initialized = true;
}
$select.change(function () {
var t0 = performance.now();
if (!initialized)
initialize();
var result = mySelectors;
$select.each(function () {
var val = $(this).val(); //you don't need to search the selected child
if (val !== 'all') {
switch ($(this).prop('id')) {
case 'select-server':
result = result.filter(obj => {
return obj.server === val;
});
break;
case 'select-track':
result = result.filter(obj => {
return obj.track === val;
});
break;
case 'select-car':
result = result.filter(obj => {
return obj.car === val;
});
break;
case 'select-date':
var selectedDate = new Date(new Date().setDate(new Date().getDate() - val)).getTime(); // timestamp
result = result.filter(obj => {
return obj.date > selectedDate;
});
}
}
});
$($statsSection).hide();
$.each(result, function (i, e) {
$(e.element).show();
});
var t1 = performance.now();
console.log("Search performance " + (t1 - t0) + " milliseconds.");
});
var t1 = performance.now();
console.log("Initialize performance " + (t1 - t0) + " milliseconds.");.grids { clear: both;max-width: 1920px;margin: 0;}
#stats_filter_wrapper .select-wrapper { width: 25%; float:left; }
#stats_filter_wrapper .select-wrapper label { overflow: hidden; font-weight: 700; }
#stats_filter_wrapper .select-wrapper select { display: block; font-size: 16px; color: #6a6d73; line-height: 1.3; padding: 8px 25px 5px 8px; width: 100%; max-width: 100%; box-sizing: border-box; margin: 0; }
.stats-section{padding:20px 0;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="stats_filter">
<div id="stats_filter_wrapper" class="grids">
<div class="grid-3 select-wrapper server first">
<label class="server">Server</label>
<select id="select-server">
<option value="all">All</option>
<option value="NicNicFunGame">NicNicFunGame</option>
<option value="GT3_races">GT3_races</option>
</select>
</div>
<div class="grid-3 select-wrapper track">
<label class="track">Track</label>
<select id="select-track">
<option value="all">All</option>
<option value="ks_brands_hatch">ks_brands_hatch</option>
<option value="Imola">Imola</option>
<option value="Spa">Spa</option>
</select>
</div>
<div class="grid-3 select-wrapper car">
<label class="car">Car</label>
<select id="select-car">
<option value="all">All</option>
<option value="ariel_atom_v8">ariel_atom_v8</option>
<option value="rr_caterham_academy_620r">rr_caterham_academy_620r</option>
<option value="ks_porsche_911_gt1">ks_porsche_911_gt1</option>
</select>
</div>
<div class="grid-3 select-wrapper date">
<label class="date">Date</label>
<select id="select-date">
<option value="all">All</option>
<option value="7">Last 7 days</option>
<option value="30">Last 30 days</option>
<option value="182">Last 6 months</option>
<option value="365">Last 12 months</option>
</select>
</div>
</div>
</div>
<div class="stats-section" id="sectionID_1" data-server="NicNicFunGame" data-track="ks_brands_hatch" data-date="27/09/2019" data-car="ariel_atom_v8">sectionID_1</div>
<div class="stats-section" id="sectionID_2" data-server="NicNicFunGame" data-track="Imola" data-date="03/07/2019" data-car="rr_caterham_academy_620r">sectionID_2</div>
<div class="stats-section" id="sectionID_3" data-server="GT3_races" data-track="Spa" data-date="14/01/2019" data-car="ariel_atom_v8, ks_porsche_911_gt1">sectionID_3</div>
https://stackoverflow.com/questions/58197397
复制相似问题