jQuery点击时检查/取消选中单选按钮

48

我有这段代码用来在单击时检查/取消选中单选按钮。

我知道这对用户界面不太友好,但我需要它。

$('#radioinstant').click(function() {     
  var checked = $(this).attr('checked', true);
  if(checked){ 
    $(this).attr('checked', false);
  }
  else{ 
    $(this).attr('checked', true);
  }
});

上述函数不起作用。

如果我点击按钮,什么也不会发生。它仍然被选中。为什么?错误在哪里?我不是jQuery专家。我使用的是jQuery 1.3.2版本。

只是为了明确起见,#radioinstant 是单选按钮的ID。


需要注意的是,如果您还根据单选按钮的选中状态执行其他操作,则在onclick事件上可能会得到误导性的“checked”值。一种解决方案是在mousedown事件上将要分配给它的值(与其相反)分配给节点上的变量,例如this.__rval,并在onclick处理程序中检查其是否存在。如果存在,则知道其中的值是正确的,尽管this.checked可能即将更改。 - user1086498
26个回答

40

我在之前的建议基础上进行了拓展。 这对于我来说可行,即使有多个使用相同名称的单选按钮也可以。

$("input[type='radio']").click(function()
{
  var previousValue = $(this).attr('previousValue');
  var name = $(this).attr('name');

  if (previousValue == 'checked')
  {
    $(this).removeAttr('checked');
    $(this).attr('previousValue', false);
  }
  else
  {
    $("input[name="+name+"]:radio").attr('previousValue', false);
    $(this).attr('previousValue', 'checked');
  }
});

3
这正是我所需要的(谢谢你)。我在http://jsfiddle.net/dan74/6KYVP/添加了一个演示——如果一个单选按钮默认为选中状态,则需要点击两次才能取消选中(我可以接受这一点),但除此之外,单选按钮的行为符合预期(可以取消选中)。 - Dan
1
需要进行一处更正... $("input[name='" + name + "']:radio").attr('previousValue', false); ...请注意在+name+周围的单引号... ' " + name + " ' - Terence Golla

28
如果你只想要一个能够被选中的复选框,不需要用jQuery来实现。这是复选框的默认功能。 但是,如果你想要执行其他操作,可以使用jQuery来添加它们。在jQuery 1.9之前,您可以使用$(this).attr('checked') 来获取值,而不是使用$(this).attr('checked', true); ,因为后者将设置值。 这里有一个演示,展示了默认复选框功能与您在jQuery中所做的区别。
注意:在JQuery 1.6之后,您应该在所有三个地方都使用$(this).prop;,而不是$(this).attr(感谢@Whatevo指出这一点,请参阅此处以获取更多详细信息)。 更新:

抱歉,忘记了要求必须是单选按钮。您仍然可以考虑使用复选框,但这里是单选输入版本的更新代码。它通过将previousValue设置为复选框的属性来工作,因为我认为1.3.2版本不支持prop。您还可以将其存储在作用域变量中,因为有些人不喜欢在字段上设置随机属性。这里是新的示例

更新2: 如Josh所指出的那样,先前的解决方案只适用于一个单选按钮。这里是一个函数,它可以通过名称使一组单选按钮取消选择,并提供了一个演示
var makeRadiosDeselectableByName = function(name){
    $('input[name=' + name + ']').click(function() {
        if($(this).attr('previousValue') == 'true'){
            $(this).attr('checked', false)
        } else {
            $('input[name=' + name + ']').attr('previousValue', false);
        }

        $(this).attr('previousValue', $(this).attr('checked'));
    });
};

1
我最喜欢检查“checked”状态的方法是使用$(this).is(':checked')。 - JakeJ
1
注意到 .attr() 在较新版本的 jQuery(在这种情况下为1.9.1)中不起作用。如果您想采用这种方法,请改用 $(this).prop("checked");。 - Whatevo
你的单选按钮示例在有多个单选按钮时无法正常工作(这也是使用单选按钮的整个目的)。Jurrie的答案更接近解决方案。 - Josh Stodola
@JoshStodola 谢谢,现在已经修复了。 - Briguy37
var value = $('#radGroup').is(':checked') ? 1 : 0; 变量值= $(“#radGroup”).is(“:checked”)?1:0; - JoshYates1980

13

你现在所做的不是获取选中的值,而是设置它:

var checked = $(this).attr('checked', true);

为了正确获取它:

var checked = $(this).attr('checked');

一个可用的解决方案(包含多个具有不同值的单选按钮):

// select radio buttons group (same name)
var radioButtons = $("input[type='radio'][name='rr']");
// save initial ckecked states
var radioStates = {};
$.each(radioButtons, function(index, rd) {
    radioStates[rd.value] = $(rd).is(':checked');
});

// handle click event
radioButtons.click(function() {
    
    // check/unchek radio button
    var val = $(this).val();  
    $(this).prop('checked', (radioStates[val] = !radioStates[val]));    
    
    // update other buttons checked state
    $.each(radioButtons, function(index, rd) {
        if(rd.value !== val) {
            radioStates[rd.value] = false; 
        }
    });
});

附言: 对于 jQuery 版本小于 1.6,应使用 $().attr 而非 $().prop

演示: jsFiddle


是的,它不起作用,因为每当您单击时,都将其状态设置为checked=true(对于单选按钮,单击即为选中)。 - manji
你需要将其状态存储在全局变量中并进行检查。请参见我的编辑。 - manji
为什么你会认为只有一个单选按钮就是一个“可行的解决方案”?在那种情况下使用一个单选按钮没有任何意义……因为通常都有多个选项。 - Josh Stodola
@JoshStodola,不要生气,问题只涉及一个单选按钮。但是,你关于多个单选按钮需要解决方案的说法是正确的。回答已更新。 - manji

12

最佳且最简短的解决方案。它适用于任何具有相同名称的单选按钮组。

$(document).ready(function(){
    $("input:radio:checked").data("chk",true);
    $("input:radio").click(function(){
        $("input[name='"+$(this).attr("name")+"']:radio").not(this).removeData("chk");
        $(this).data("chk",!$(this).data("chk"));
        $(this).prop("checked",$(this).data("chk"));
        $(this).button('refresh'); // in case you change the radio elements dynamically
    });
});

更多信息,请点击这里

享受吧。


1
可以工作,但我必须刷新按钮才能更新它们...在结尾添加了以下代码 $(this).button('refresh'); - JoMojo

2
我认为问题在于:如果你有多个单选按钮,其中一个被点击后,就没有办法将它们全部取消选择。需要的是一个“无或只有一个”选择器,所以复选框并不合适。你可以有一个“清除”按钮或类似的东西来取消所有选择,但是直接点击选定的单选按钮以取消选择并返回“无”状态会更好,这样就不会在用户界面上添加额外的控件。
使用单击处理程序的问题在于,当它被调用时,单选按钮已经被选中了。你不知道这是初始单击还是对已经选中的单选按钮的第二次单击。因此,我使用两个事件处理程序,mousedown设置前一个状态,然后使用上面提到的click处理程序:
$("input[name=myRadioGroup]").mousedown(function () 
{
    $(this).attr('previous-value', $(this).prop('checked'));
});

$("input[name=myRadioGroup]").click(function () 
{
    var previousValue = $(this).attr('previous-value');

    if (previousValue == 'true')
        $(this).prop('checked', false);
});

1
最后,唯一正确解决问题的方法是:当单击事件发生时,无线电已经被检查,使得所有依赖于选中状态的解决方案都变得毫无用处。 - Félix Adriyel Gagnon-Grenier

2

toggleAttr()是由这个非常好用且小巧的插件提供的。

示例代码

$('#my_radio').click(function() {
    $(this).toggleAttr('checked');
});

/**
 * toggleAttr Plugin
 */
jQuery.fn.toggleAttr = function(attr) {
    return this.each(function() {
        var $this = $(this);
        $this.attr(attr) ? $this.removeAttr(attr) : $this.attr(attr, attr);
    });
};

更有趣的是,演示

您可以将单选按钮放置在标签或按钮标记中,并进行一些不错的操作。


2

        $(document).on("click", "input[type='radio']", function(e) {
            var checked = $(this).attr("checked");
            if(!checked){
                $(this).attr("checked", true);
            } else {
                $(this).removeAttr("checked");
                $(this).prop("checked", false);
            }
        });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" name="test" id="radio" /> <label for="radio">Radio</label>


1

-- 编辑 --

看起来你的代码确实是在强制单选框输入像复选框输入一样。你可以考虑使用复选框输入而不需要 jQuery。但是,如果你想要强制,就像 @manji 说的那样,你需要在点击处理程序之外存储值,然后在每次点击时将其设置为相反的值。@manji 的答案是正确的,我只想补充一点,你应该缓存 jQuery 对象而不是重新查询 DOM:

var $radio = $("#radioinstant"),
    isChecked = $radio.attr("checked");

$radio.click(function() {

    isChecked = !isChecked;
    $(this).attr("checked", isChecked);

});

1
这只能在第一次起作用。但是如果用户决定再次检查它,它将不起作用。用户在做事情时可能会改变他们的决定。我该如何在每次单击时检查它是否未选中并取消选中它?谢谢。 - DiegoP.
我不确定你想要实现什么?你是想让单选框的行为像复选框吗? - Code Maverick

1
改进版的Jurrie的答案。
$('#myRadio').off('click').on('click', function() {
  if ($(this).data('checked')) {
    $(this).removeAttr('checked');
    $(this).data('checked', false);
  } else {
    $(this).data('checked', true);
  }
});

现场演示


1
$(document).ready(function(){ $("input:radio:checked").data("chk",true); })
当文档准备就绪时,执行以下操作:将已选中的单选按钮设置为“chk”数据。
$("input:radio").click(function(){
    $("input[name='"+$(this).attr("name")+"']:radio").not(this).removeData("chk");

    $(this).data("chk",!$(this).data("chk"));

    $(this).prop("checked",$(this).data("chk"));
});

});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接