取消选中 bootstrap 单选按钮

Uncheck bootstrap radio button

我正在尝试取消选中按钮组中用标签包裹的单选按钮,如下所示:

<div>
            <label class="btn btn-primary">
              <input type="radio" name="radio1" class="radio1" />
    Radio1
            </label>
</div>
<div>
            <label class="btn btn-primary">
              <input type="radio" name="radio2" class="radio2" />
    Radio2
            </label>
</div>
$('.btn').on('click', function(e) {
      // Check if another option was previously checked
      if ($(this).parent().parent().find(':radio:checked').length == 1) {
        inner_input = $(this).find('input');
        if (inner_input.prop('checked')) {
          e.stopImmediatePropagation();
          e.preventDefault();
          inner_input.prop('checked', false);
          $(this).removeClass('active');
        }
});

不幸的是,它不起作用,即使在第二次点击后标签仍然有效。

为什么会这样?

我们先看看什么是clickmouseupmousedown事件:

鼠标按下

Fires when the user depresses the mouse button.

鼠标弹起

Fires when the user releases the mouse button.

点击

Fires when a mousedown and mouseup event occur on the same element. Fires when the user activates the element that has the keyboard focus (usually by pressing Enter or the space bar).

所以当使用 click 事件时,单选按钮被选中,这意味着 radio.is(':checked') 将始终 return true 除非您禁用默认行为。所以你可以通过两种方式做你想做的事:


1- 使用 Mouseup 事件,在这种情况下,您可以确定单选按钮的状态,无论它是否被选中或 not.But 通过这种方式您需要一些额外的代码来禁用 click 事件

的默认行为
$('label').on('mouseup', function(e){
    var radio = $(this).find('input[type=radio]');

  if( radio.is(':checked') ){
    radio.prop('checked', false);

  } else {
    radio.prop('checked', true);

  }

});

// Disable default behavior
$('label').click(function(e){
    e.preventDefault();
});

Fiddle


和 2 ,您可以将它们全部包装在一起,禁用 click 的默认行为并在一个事件中完成其余部分:

$('label').click(function(e) {
    e.preventDefault();

    var radio = $(this).find('input[type=radio]');

    if (radio.is(':checked')) {
        radio.prop('checked', false);

    } else {
        radio.prop('checked', true);

    }
});

Fiddle

我确实使用了 2 个不同的事件来回答这个问题,有时在更复杂的问题中你可能被迫使用 mouseup 事件而不是 click

当前答案中的解决方案适用于无线电输入。但它不适用于按钮组。为了避免其他搜索者的麻烦,以下代码可能会有所帮助:

$('label').click(function(e) {
  e.preventDefault();

  var radio = $(this).find('input[type=radio]');

  if (radio.is(':checked')) {
    e.stopImmediatePropagation();
    $(this).removeClass("active");
    radio.prop('checked', false);
  } else {
    radio.prop('checked', true);

  }
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

<div class="btn-group btn-group-toggle" data-toggle="buttons">
  <label class="btn btn-outline-secondary active">
        <input type="radio" name="options" id="option1" autocomplete="off" checked>
        option 1
    </label>
  <label class="btn btn-outline-secondary">
        <input type="radio" name="options" id="option2" autocomplete="off">
        option 2
    </label>
  <label class="btn btn-outline-secondary">
        <input type="radio" name="options" id="option3" autocomplete="off">
        option 3
    </label>
</div>