我有几个复选框可根据选中的复选框过滤产品。单击复选框时,过滤器将起作用,并且会将产品ID添加到阵列中。正如您所看到的,两个过滤器都具有一些相同的ID,因此如果它们单击多个输入框,我想确保仅将ID推入数组一次。例如。如果他们选择了input.white并选择了input.greymelange,那么他们点击了filter-btn我只想重复一次推送id。有没有办法可以做到这一点?
JQUERY
var productIds = [""];
$(document).on('click', 'a.filter-btn', function(e){
$( ".listingTemplate" ).html("");
if ($('input.white').is(':checked')) {
productIds.push("4021401143741", "4021402266227");
}
if ($('input.greymelange').is(':checked')) {
productIds.push("4021401143741", "4021402266227","4021402266418", "4021401143796");
}
});
HTML
<input type="checkbox" id="white" class="white" value="white" />
<input type="checkbox" id="greymelange" class="greymelange" value="greymelange" />
<a href="#" class="filter-btn">filter</a>
答案 0 :(得分:4)
您可以使用$.inArray()
和$.each()
1)将所有新值保留在数组 deArray
中
2)使用$.each
迭代此数组,然后查找它是否在 productIds
使用inArray()
if ($('input.greymelange').is(':checked')) {
var deArray = ["4021401143741", "4021402266227", "4021402266418", "4021401143796"];
$.each(deArray, function (i, j) {
if ($.inArray(j, productIds) == -1) {
productIds.push(j);
}
});
}
建议:不要在数组中声明空字符串。
var productIds = [""]; //considered as an string. This will affect
//when you check length, now it is 1
var productIds = []; //length is 0
最后,
var productIds = [];
$(document).on('click', 'a.filter-btn', function (e) {
$(".listingTemplate").html("");
if ($('input.white').is(':checked')) {
var dArray = ["4021401143741", "4021402266227"];
$.each(dArray, function (i, j) {
if ($.inArray(j, productIds) == -1) {
console.log(j)
productIds.push(j);
}
})
}
if ($('input.greymelange').is(':checked')) {
var deArray = ["4021401143741", "4021402266227", "4021402266418", "4021401143796"];
$.each(deArray, function (i, j) {
if ($.inArray(j, productIds) == -1) {
productIds.push(j);
}
})
}
console.log(productIds)
});
<强> JSFiddle 强>
答案 1 :(得分:2)
如果您只有一组固定的产品ID,为什么需要一个可变长度数组来存储哪些产品ID?
我建议建立一个包含你可以使用的逻辑的对象。
function productMapper() {
var colorToIdMap = {
'white' = [
'4021401143741',
'4021402266227'
],
'greymelange' = [
'4021401143741',
'4021402266227',
'4021402266418',
'4021401143796'
]
};
var selectedIds = [];
function selectIds(color) {
this.selectedIds = [];
var colorIds = this.colorToIdMap[color];
for(i = 0; i < colorIds.length; i++) {
var currentId = colorIds[i];
if(this.selectedIds.indexOf(currentId) === -1) {
this.selectedIds.push(currentId);
}
}
}
function getSelectedIds() {
return this.selectedIds;
}
}
用法可能是:
var selectedProductMap = new productMapper();
$(document).on('click', 'a.filter-btn', function(e){
$( ".listingTemplate" ).html("");
if ($('input.white').is(':checked')) {
selectedProductMap.selectIds('white');
}
if ($('input.greymelange').is(':checked')) {
selectedProductMap.selectIds('greymelange');
}
});
这样做的好处是,当您添加新颜色和产品ID时,很容易将它们添加到此类中(或者从数据库中动态构建该类部分。
我还建议考虑重构HTML,这样就不需要为每个颜色选项添加if
条件。也许给所有复选框输入一个公共类,并从input属性派生颜色值。这样的事情可能会出现在你的onclick函数中:
$('input.filterCheckbox').each(function(index.value)) {
var $currentCheckbox = $(this);
if($currentCheckbox.is(':checked')) {
selectedProductMap.selectIds($currentCheckbox.val());
}
}
var currentlySelectedIds = selectedProductMap.getSelectedIds();
答案 2 :(得分:0)
在添加到列表之前,您需要检查项目是否包含在内。不幸的是,这并不像应该的那样容易,但下面的堆栈解释了:How do I check if an array includes an object in JavaScript?
由于您将此标记为jQuery,因此以下(示例)代码可能适合您:
if ($.inArray("4021401143741", productIds) === -1)
productIds.push("4021401143741");
有关此致电see here的更多信息。祝你好运!
答案 3 :(得分:0)
要检查数组中是否已存在某个项目,您可以使用Array.indexOf
。请注意,在IE中本地不存在&lt; 9,但我已经发布了一个剪下来的代码,如果它不可用,它将把它添加到Array原型中。
var products = [];
function addProducts() {
for(var i = 0, l = arguments.length; i < l; i++) {
if(products.indexOf(arguments[i]) === -1) {
products.push(arguments[i]);
}
}
}
//Add indexOf if it doesn't exist natively
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(elt) {
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for(; from < len; from++) {
if(from in this && this[from] === elt)
return from;
}
return -1;
};
}
然后,要使用这些新功能,您可以将代码修改为:
$(document).on('click', 'a.filter-btn', function(e) {
if($('input.white').is(':checked')) {
addProducts("4021401143741", "4021402266227");
}
if($('input.greymelange').is(':checked')) {
addProducts("4021401143741", "4021402266227","4021402266418", "4021401143796");
}
});
正如旁注。如果可以避免,则不应将事件绑定到文档。如果您使用大量事件,则将事件绑定到文档可能会导致性能问题。每次触发click
事件时,此函数将运行以检查目标是否与指定的目标匹配。要限制此性能命中,您应该将它们绑定到最接近的非更改元素。在表单内部输入的示例中,您可以将其添加到表单中。
答案 4 :(得分:0)
将以下代码添加到缺血条件中。 // Continue execution
推送价值观。
isSet = false;
currentVal = '999999999999';
$.each(productIds, function( index, value ) {
if(value == currentVal){
isSet = true;
}
});
if(isSet){
// Continue execution
} else {
// failure
}
答案 5 :(得分:0)
它需要是一个数组吗?听起来你最好不要使用普通物体:
productIds[ 420… ] = true;
这取决于你的其余代码,但听起来你想要实现一个哈希/查找表/字典而不是一个数组 - 以这种方式检查存在也会更直接。