单击时如何选中/取消选中单选按钮?

IT技术 javascript jquery
2021-02-25 08:15:23

我希望能够通过单击来取消选中一个单选按钮。

所以,如果一个单选按钮没有被选中,我想选中它,如果它被选中,我想取消选中它。

这不起作用:

$('input[type=radio]:checked').click(function(){
    $(this).attr('checked', false);
});

我现在无法检查单选按钮。

6个回答

不是要替换复选框,而是要允许无线电组返回到未选中状态。这很棘手,因为无线电选择不像正常事件。

浏览器处理普通事件链之外的单选按钮。因此,带有 event.preventDefault() 或 event.stopPropagation() 的单选按钮上的单击处理程序不会阻止检查单选按钮。.removeAttr('checked') 必须在 setTimeout 中完成以允许事件完成,并且浏览器检查单选按钮(再次),然后 setTimeout 将触发。

这也可以正确处理用户启动鼠标按下但在鼠标按下之前离开单选按钮的情况。

//$ = jQuery;
$(':radio').mousedown(function(e){
  var $self = $(this);
  if( $self.is(':checked') ){
    var uncheck = function(){
      setTimeout(function(){$self.removeAttr('checked');},0);
    };
    var unbind = function(){
      $self.unbind('mouseup',up);
    };
    var up = function(){
      uncheck();
      unbind();
    };
    $self.bind('mouseup',up);
    $self.one('mouseout', unbind);
  }
});

我希望这有帮助

先生,你是个天才。
2021-04-22 08:15:23
这让我发疯了!非常感谢你!
2021-04-23 08:15:23
它确实适用于 Firefox 18,伙计!(同意天才的说法!)
2021-04-25 08:15:23
只是要指出,今天这仍然是一个很好的解决方案。另外,$self.bind('mouseup', up)可以替换为$self.mouseup(up)$self.unbind('mouseup',up)to$self.off('mouseup')以摆脱不推荐使用的方法。最后,我使用标签方法实现了这一点,以防万一有人想知道在这种情况下这是否也有帮助:)
2021-04-25 08:15:23
未来的读者,在盲目复制此解决方案之前,请阅读此答案(stackoverflow.com/a/27476660/8430155)。
2021-05-04 08:15:23

试试这个:

$('input[type=radio]').click(function(){
    if (this.previous) {
        this.checked = false;
    }
    this.previous = this.checked;
});
在 chrome 中,现在它可以工作。有没有其他人可以证实或反驳这一点。
2021-04-15 08:15:23
由于@HexInteractive 在回答中陈述的原因,您的解决方案效果不佳。我在 Webkit 中,它的行为非常不稳定……是的,它允许取消选择单选按钮,但大多数情况下,您必须单击单选按钮两次才能选择它们。 jsfiddle.net/sparky672/KdZG7
2021-04-22 08:15:23
也适用于 Firefox v68
2021-04-24 08:15:23
在 Chrome 版本 68(截至 2018 年 8 月)中可以顺利运行。
2021-05-13 08:15:23
不能远程工作。使用单选按钮的唯一原因是允许互斥选择。因此,添加两个或更多单选按钮并观察此失败,因为当另一个按钮更改此按钮的选中状态但上一个未反映该状态时。
2021-05-14 08:15:23

接受的答案不适用于移动设备。它依赖于 setTimeout 和与鼠标事件相关的绑定,这些事件不会在平板电脑/移动设备上触发。
我的解决方案是使用“单击”事件处理程序和自定义类状态手动跟踪所选状态。

  1. 处理单选输入元素上的点击事件
  2. 检查单击的元素上是否存在“选定”类
  3. 如果是,(意味着它之前被点击过),删除类并取消选中元素,返回
  4. 如果没有,请从所有同名元素中删除该类,并将其添加到单击的元素中。

无需阻止默认行为。这是Jquery中的代码:

$("input:radio").on("click",function (e) {
    var inp=$(this); //cache the selector
    if (inp.is(".theone")) { //see if it has the selected class
        inp.prop("checked",false).removeClass("theone");
        return;
    }
    $("input:radio[name='"+inp.prop("name")+"'].theone").removeClass("theone");
    inp.addClass("theone");
});

http://jsfiddle.net/bhzako65/

自定义类与按钮状态无关。您可以随意设置样式,但选中状态与类无关。
2021-05-07 08:15:23
非常有趣,我正在努力理解为什么添加类会删除选定的状态:o)
2021-05-09 08:15:23

我一定很想念它,但经过这么多年,AFAIK 上面的解决方案似乎都不起作用,或者我可能只是愚蠢。

除非在同一组中有多个单选按钮,否则绝对没有理由使用单选按钮。如果它是一个单独的单选按钮,那么只需使用一个复选框。使用单选按钮的原因是为了选择互斥选项之一。这意味着任何只查看单个按钮的解决方案都将失败,因为单击一个按钮会影响其他按钮的状态

换句话说,由于我们使用的是radioboxes,因此解决方案需要为

<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>

这是查看所有按钮的一个。

这似乎有效

document.querySelectorAll(
    'input[type=radio][name=foo]').forEach((elem) => {
  elem.addEventListener('click', allowUncheck);
  // only needed if elem can be pre-checked
  elem.previous = elem.checked;
});

function allowUncheck(e) {
  if (this.previous) {
    this.checked = false;
  }
  // need to update previous on all elements of this group
  // (either that or store the id of the checked element)
  document.querySelectorAll(
      `input[type=radio][name=${this.name}]`).forEach((elem) => {
    elem.previous = elem.checked;
  });
}
body { font-size: xx-large; }
label, input {
  /* added because a second click to unselect radio often
     appears as a double click to select text */
  -webkit-user-select: none;
  user-select: none;
}
<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>

请注意是否elem.previous担心您可以使用elem.dataset.previous

另一种解决方案是存储选中的按钮

function makeRadioboxGroupUnCheckable(groupSelector) {

  let currentId;

  document.querySelectorAll(groupSelector).forEach((elem) => {
    elem.addEventListener('click', allowUncheck);
    // only needed if can be pre-checked
    if (elem.checked) {
      currentId = elem.id;
    }
  });

  function allowUncheck(e) {
    if (this.id === currentId) {
      this.checked = false;
      currentId = undefined;
    } else {
      currentId = this.id;
    }
  }
}

makeRadioboxGroupUnCheckable('input[type=radio][name=foo]');
body { font-size: xx-large; }
label, input {
  /* added because a second click to unselect radio often
     appears as a double click to select text */
  -webkit-user-select: none;
  user-select: none;
}
<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>

这是真正的解决方案......

var check;

$('input[type="radio"]').hover(function() {
    check = $(this).is(':checked');
});

$('input[type="radio"]').click(function() {
    check = !check;
    $(this).attr("checked", check);
});

试试吧,它对我有用!

我必须稍微调整一下,以在我希望通过单击 parent 来选择/取消选择单选按钮的情况下工作div但我所要做的就是改变第一个$('input[type="radio"]')to$('div.parentClass')和 the check = $(this).is(':checked');tocheck = $(this).find('input[type="radio"]').is(':checked');
2021-05-06 08:15:23