我有4个复选框。如果按下所有4个复选框,我想生成Number
15,例如" 0000 1111"。如果没有单击任何复选框,则它应该产生0,例如" 0000 0000"。换句话说,单击复选框时,应设置关联的位,否则应取消设置。每个复选框都以2的幂提升,以便定位下一位:
<input type="checkbox" name="validation_rules" id="inlineCheckbox1" value="1">
<input type="checkbox" name="validation_rules" id="inlineCheckbox2" value="2">
<input type="checkbox" name="validation_rules" id="inlineCheckbox4" value="4">
<input type="checkbox" name="validation_rules" id="inlineCheckbox8" value="8">
我可以正常设置位:
以下是相关方法:
listen_for_enabled_change: function(){
$form.on('click', 'input[name="validation_rules"]', function(){
var $hidden = $(this).closest('.field-border').find("input[type='hidden'][name='result']");
var new_val;
if($(this).get(0).checked) {
new_val = $hidden.val() | $(this).val();
} else {
var mask = 1 << $(this).val()/2;
new_val = $hidden.val() & ~mask;
}
$hidden.val(new_val);
})
}
不幸的是,取消设置该位在上面的代码中不起作用。例如,如果隐藏的输入字段值为8.然后我取消选中值为8的复选框,它应该生成0.但是,它根本不会更改该值。它只返回Number
8.我可能做错了什么?
答案 0 :(得分:1)
我认为你的问题在这里:
var mask = 1 << $(this).val()/2;
new_val = $hidden.val() & ~mask;
值为[1,2,4,8]
,这将导致[0,1,2,4]
的向下舍入整数。是的4
,应该是3
。
为什么不将复选框值标记为需要设置的位索引?
<input type="checkbox" name="validation_rules" id="inlineCheckbox1" value="0">
<input type="checkbox" name="validation_rules" id="inlineCheckbox2" value="1">
<input type="checkbox" name="validation_rules" id="inlineCheckbox4" value="2">
<input type="checkbox" name="validation_rules" id="inlineCheckbox8" value="3">
然后你可以:
if($(this).get(0).checked) {
// flip on the bit at the bit index
new_val = $hidden.val() | (1 << $(this).val());
} else {
// flip off the bit at the bit index
new_val = $hidden.val() & ~(1 << $(this).val());
}
或整件事,清理了一下:
var $this = $(this);
var $hidden = $("#result");
var newVal = $hidden.val();
var bit = $this.val()
if (this.checked) {
newVal = newVal | (1 << bit);
} else {
newVal = newVal & ~(1 << bit);
}
$hidden.val(newVal);
答案 1 :(得分:1)
在我看来,基于刚检查的复选框进行的所有位掩码和移位都是不必要的复杂(过早优化?),而不是基于刚才的复选框操纵当前$hidden
值检查后,每次任何复选框的更改时,只需总计值,就可以获得更具可读性/更少错误的代码:
$form.on('change', 'input[name="validation_rules"]', function () { // 'change' is more robust than 'click' here
var new_val = 0;
$('input[name="validation_rules"]').each(function(i, elem) {
if (elem.checked) {
new_val += parseInt(elem.value, 10);
}
});
$hidden.val(new_val);
})
答案 2 :(得分:0)
我必须遗漏一些东西,但......简单的序列化会做:
你可以将一组元素传递给一个将你的位掩码加起来的函数。
var getBitmask = function(els){
return Array.prototype.reduce.call(Array.prototype.filter.call(els, function(el){
return el.checked;
}), function(a, b){
return {value: ~~a.value + ~~b.value};
}).value;
};
console.log(getBitmask(document.querySelectorAll('input[type=checkbox]')));
以上工作没有jQuery。
您也可以围绕元素索引自动构建位掩码。