jQuery .change DRY代码

时间:2015-07-16 17:19:16

标签: javascript jquery dry

我使用了' bootstraptoggle'插入。我正在根据选中的框构建一个mongoDB查询。

代码完美无缺,但我讨厌重复.change,有没有办法让这个干?

我有以下代码

HTML

<div id="checkBoxContainer" class="container">
     <label class="checkbox-inline">
          <input type="checkbox" id="optionOne" data-onstyle="success" data- offstyle="danger" data-toggle="toggle">
     </label>
     <label class="checkbox-inline">
          <input type="checkbox" id="optionTwo" data-onstyle="success" data- offstyle="danger" data-toggle="toggle">
     </label>
</div>

JS

$('#optionOne').change(function() {
    if ($(this).prop('checked') == true) {
        queryBuilder.push($(this).attr("id"));
    } else if ($(this).prop('checked') == false) {
        queryBuilder.splice($(this).attr("id"));
    }
    console.log(queryBuilder);
});


$('#optionTwo').change(function() {
    if ($(this).prop('checked') == true) {
        queryBuilder.push($(this).attr("id"));
    } else if ($(this).prop('checked') == false) {
        queryBuilder.splice($(this).attr("id"));
    }
    console.log(queryBuilder);
});

我搜索过并试过以下但没有运气。

$('document').on('change','#checkBoxContainer', function() {    
      if ($(this).prop('checked') == true) {
        queryBuilder.push($(this).attr("id"));
    } else if ($(this).prop('checked') == false) {
        queryBuilder.splice($(this).attr("id"));
    }
    console.log(queryBuilder);

});

2 个答案:

答案 0 :(得分:3)

  

有没有办法让这个干?

$('#optionOne, #optionTwo').change(...);

这称为selector group。更改处理程序中的所有代码都不是特定于它所连接的元素,因此纯粹是将它连接到两个元素。

无关,但是:这条线是可疑的:

queryBuilder.splice($(this).attr("id"));

splice期望至少有两个参数:开始处理的索引,以及要在该位置删除的元素数(如果你有更多的参数,则可能为0)指定要插入的内容。

如果您的目标是从数组中删除$(this).attr("id")的值,则不会这样做。代替:

var index = queryBuilder.indexOf($(this).attr("id"));
if (index != -1) {
    queryBuilder.splice(index, 1);
}

如果它在那里找到它,并将其删除。

旁注:

正如斜视所说,$(this).attr("id")只是写this.id的漫长道路,而$(this).prop("checked")只是写this.checked的漫长道路。 : - )

在进行比较时,从来没有任何理由写== true很少,写=== true的理由)。

最后,由于checked只能是真或假,所以不需要第二个if

所以:

$('#optionOne, #optionTwo').change(function() {
    var index;
    if (this.checked) {
        queryBuilder.push(this.id);
    } else {
        index = queryBuilder.indexOf(this.id);
        if (index != -1) {
            queryBuilder.splice(index, 1);
        }
    }
    console.log(queryBuilder);
});

或略短:

$('#optionOne, #optionTwo').change(function() {
    var index;
    if (this.checked) {
        queryBuilder.push(this.id);
    } else if ((index = queryBuilder.indexOf(this.id)) != -1) {
        queryBuilder.splice(index, 1);
    }
    console.log(queryBuilder);
});

明显过度分析,我注意到如果我们认为在没有选中复选框时它有可能出现在阵列中,我们就会应该更加防守,避免两次进攻:

$('#optionOne, #optionTwo').change(function() {
    var index = queryBuilder.indexOf(this.id);
    if (this.checked && index == -1) {
        queryBuilder.push(this.id);
    } else if (!this.checked && index != -1) {
        queryBuilder.splice(index, 1);
    }
    console.log(queryBuilder);
});

好的,我现在就停下来。 : - )

Gah,还有一件事:一些非常旧的浏览器没有Array#indexOf,所以如果你需要支持它们,你需要添加一个垫片或者使用jQuery严重错误的$.inArray代替。要使用inArray,请将queryBuilder.indexOf(this.id)更改为$.inArray(queryBuilder, this.id)(其他任何内容都不需要更改)。

答案 1 :(得分:1)

使用普通项的公共类是最简单的方法:

<input class="option-class" type="checkbox" id="optionTwo">

$('.option-class').change(/* your handler code */);

虽然ID是目标人群中最容易使用的选择器,但是在使用类重复组件时,通过定位元素组而不是一次一个元素,可以更轻松地干掉代码/ p>