javascript中的未设置位产生错误值

javascript中的未设置位产生错误值,javascript,bit-manipulation,Javascript,Bit Manipulation,我有4个复选框。如果所有4个复选框都被按下,我想生成编号15,例如“0000 1111”。如果未单击任何复选框,则应生成0,例如“0000”。换句话说,单击复选框时,应设置相关位,否则应取消设置。每个复选框都以2的幂递增,以确定下一位的目标: <input type="checkbox" name="validation_rules" id="inlineCheckbox1" value="1"> <input type="checkbox" name="validation_

我有4个复选框。如果所有4个复选框都被按下,我想生成
编号
15,例如“0000 1111”。如果未单击任何复选框,则应生成0,例如“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);
  })
}
listen\u查找启用的\u更改:函数(){
$form.on('click','input[name=“validation_rules”]”,function(){
var$hidden=$(this).closest('.field border').find(“输入[type='hidden']][name='result']”);
var new_val;
if($(this).get(0).checked){
new_val=$hidden.val()|$(this.val());
}否则{

var mask=1我认为你的问题在于:

  var mask = 1 << $(this).val()/2;
  new_val = $hidden.val() & ~mask;
然后你可以:

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());
}
if($(this).get(0).checked){
//在位索引处翻转位

new_val=$hidden.val()|(1我肯定遗漏了什么,但是…简单的序列化就可以了:

您只需将一组元素传递到一个函数中,该函数将添加您的位掩码

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


您也可以围绕元素索引自动构建位掩码。

在我看来,所有基于刚刚选中复选框的位掩码和移位都是不必要的复杂(过早优化?),而不是根据刚才选中的复选框来操作当前的
$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);
})

旁注:
$(此).get(0)
会让你回来的
这是你想要的吗?@royhowie是的,这就是我的想法。我的代码的问题就在这里:var mask=1似乎你想左移值0,1,2,3,而不是0,1,2,4。对吗?或者根本不移位和除法,因为它们已经占据了你想要的位位置。像这样:…她e是一个jQuery更少的版本。速度更快,更不冗长。我有一种预感,@Donato想要使用二进制操作。但如果不是,这就是方法。我知道这是一个问题,但这应该得到解决。
$(this)。get(0).checked
@skint谢谢我也修复了这个问题。我同意,对jQuery的依赖太多了。要么是那样,要么是
$this[0]。checked
或者jQuery惯用的
$this.is(':checked')
。请选择:)两者都不是…
这个。选中了
,我将完全跳过创建jQuery对象,只使用它的
.value
属性。
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]')));
$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);
})