我正在尝试根据数据属性过滤结果。在大多数情况下,我认为我在那里(它适用于前三个选择器),但是尝试将日期选择器纳入等式时遇到了麻烦。在这一点上,我对我的方法的看法完全正确-我可以根据需要更改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();
}
});
因此,对于非日期项目,您的技术是为应该包含的元素计算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的形式运行。因此,第二步将在show()操作中应用dateInclude过滤器。
$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();
第一行(下面)可抢先隐藏所有数据div。
$statsSection.hide();
下一行(下面)在过滤器上进行操作以确保它们都具有值。如果没有日期过滤器,我们将插入一个全部匹配项,其他选择框的“包含”过滤器也将全部插入。
include = (dateInclude.length > 0 && include === '' ? '*' : include);
dateInclude = (dateInclude.length === 0 ? ['*'] : dateInclude );
最后,如下所述。
$statsSection.filter(include).filter(dateInclude.join()).show();
为了帮助可视化,我在小提琴中添加了一些输出
例如,选择服务器= NicNicFunGame,并且日期=最近六个月将产生过滤器:
$statsSection.filter("[data-server='NicNicFunGame']").filter("[data-date='27/09/2019'],[data-date='03/07/2019']").show();
您可以将所有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>