Twitter Bootstrap 获取复选框按钮组的状态

Twitter Bootstrap getting state of checkbox button group

有几个问题与 Twitter Bootstrap 的按钮 radio/checkbox 组有关,但 none 似乎属于新的 Bootstrap 约定(我正在使用v3.3.4) 或者我在解决我的问题。

旧的约定是声明一个 <div class="btn-group"> 包围多个 <button>,并且周围的 div 也有一个 data-toggle 属性 buttons-checkboxbuttons-radio 看起来像这样:

<div class="btn-group" data-toggle="buttons-checkbox">
    <button type="button" class="btn btn-primary">Btn 1</button>
    <button type="button" class="btn btn-primary">Btn 2</button>
    <button type="button" class="btn btn-primary">Btn 3</button>
</div>

但是,创建此类组的惯例已发生变化,如按钮 (http://getbootstrap.com/javascript/#buttons-checkbox-radio) 的 Bootstrap Javascript 页面所示:

<div class="btn-group" data-toggle="buttons">
  <label class="btn btn-primary active">
    <input type="checkbox" autocomplete="off" checked> Checkbox 1 (pre-checked)
  </label>
  <label class="btn btn-primary">
    <input type="checkbox" autocomplete="off"> Checkbox 2
  </label>
  <label class="btn btn-primary">
    <input type="checkbox" autocomplete="off"> Checkbox 3
  </label>
</div>

如您所见,按钮现在实际上是带有 checkboxradio 类型子输入字段的标签,其样式看起来像按钮。

我想设置一个 .on('click') 事件来捕获刚刚被单击的按钮的状态,但是后面的逻辑奇怪地向后(并且 Javascript 实现是似乎不完整,至少在我看来是这样——解释如下)。比如说,我想为第二个 label/checkbox/button 设置一个侦听器并确定 label/checkbox/button 是否为 active/checked - 我将设置以下代码:

$('#label2').on('click', function(){
  console.log($(this).hasClass('active'));
});

我希望上面的代码能够在按下 "activate" 和 label/checkbox/button 按钮时将 true 打印到控制台。 它打印 false。 这是因为 .on('click') 侦听器在按钮状态更改之前被触发,因此我将不得不反转我想基于的任何操作的逻辑在按钮状态。对我来说似乎倒退了。 (jsFiddle 插图:http://jsfiddle.net/mmuelle4/qq816po7/

还有一些其他库以 "sensible" 的方式捕获此问题,例如 Bootstrap Switch 库 (http://www.bootstrap-switch.org/)。 Bootstrap 开关库有一个 switchChanged 事件,可以在单击后捕获开关变化,但提供 button/checkbox post-click.

我以为我通过注册 .on('change') 处理程序而不是 .on('click') 处理程序找到了解决方案,但我得到了相同的结果。

此外,如果单击 <label>,嵌套的 <checkbox> 永远不会 sets/unsets checked 属性 -- 来吧 Bootstrap!如果状态是惰性的,为什么还要使用复选框?似乎是一个非常明显的不一致案例,其中 <label> 可以具有 active 的 class 但 <checkbox> 没有 checked 属性集...(这就是我之前所说的 Javascript 实现似乎不完整时的意思)

现在,我只需要反转我的处理程序中的逻辑,但这让我很烦。总的来说,我想我的问题是 有没有人遇到过这种情况并找到了不需要倒置逻辑的更好的解决方案(仍然只是利用 jQuery 和 Bootstrap,没有替代库?

编辑:下面有一个解决方案,但我对 <checkbox> 没有 checked 属性的评论产生了一个稍微不同的 question/discussion.可以对嵌套的 <checkbox> 执行 .is(':checked') 查询以在 .on('change') 处理程序中获得正确的状态,但是如果您检查 DOM,该属性实际上从未设置<checkbox>。令我困扰的是 DOM 没有反映我将通过 .is(':checked') 查询收到的状态...

EDIT2:我发现的另一个奇怪的怪癖是,随着对单选按钮组或复选框按钮组使用 <button> 的离开,必须采取不同的措施用于检索和更改 "faux" 按钮的某些属性。在我的例子中,我想根据各种用户输入 disable/enable 按钮,但是设置复选框的 disabled 属性 不起作用:

$('input').prop('disabled', true) //Doesn't render the button disabled

这是因为按钮现在实际上是 <input> 包含在样式为按钮的 <label> 中,所以现在必须在 [=28= 上设置 disabled ].这有点令人沮丧,但使用 jQuery 的 .parent() 方法并不难(因为我存储了一个指向输入的指针)。 令人沮丧的是,在按钮的情况下,我可以使用 .prop('disabled', true/false) 方法来更改 disabled 属性,但我不能这样做,因为现在它是 <label>

这在 jQuery 的 attr 文档 (http://api.jquery.com/attr/) 中有描述,"To retrieve and change DOM properties such as the checked, selected, or disabled state of form elements, use the .prop() method." <button> 显然是一个表单元素,而 <label> 不是(虽然我认为它会是)。现在,在我的代码中,我必须有意识地记住对真实按钮使用 .prop('disabled', true/false),对人造按钮使用 .attr('disabled', true/false)。我想看看 Bootstrap 偏离常规按钮的原因......(也许是这样 .is(':checked') 之类的东西可以工作,但它肯定会引起其他一些麻烦...... .)

EDIT3:刚了解到在 "new convention" 之后使用 <input> 包裹在 <label> 中是 不需要。您仍然可以使用一个按钮,并且会出现预期的 radio/checkbox 行为......白白头疼了。你为什么不展示这两个选项,Bootstrap???

Boot strap 已经负责在转换后的原始元素上触发事件。所以你不必担心检查 class.

您只需为原始输入设置事件并检查原始输入的状态

$('label > input[type=checkbox]').on('change', function () {
    console.log($(this).is(':checked'));
});

演示http://jsfiddle.net/qq816po7/1/