如何通过单击取消选中单选按钮?

时间:2012-06-04 06:05:42

标签: javascript html radio-button

与复选框不同,用户单击后无法取消选择单选按钮。有没有什么办法可以使用Javascript以编程方式切换它们?这最好不使用jQuery。

27 个答案:

答案 0 :(得分:46)

您可以将HTML对象的属性checked设置为false,如下所示:

document.getElementById('desiredInput').checked = false;

JavaScript example

jQuery example

PS:按住 Ctrl 键取消选中。

答案 1 :(得分:14)

单选按钮用于组,由共享相同的name属性定义。然后单击其中一个取消选择当前选定的一个。为了允许用户取消他所做的“真实”选择,你可以包括一个对应于空选择的单选按钮,如“不知道”或“无应答”。

如果您想要一个可以选中或取消选中的按钮,请使用复选框。

可以(但通常不相关)取消选中JavaScript中的单选按钮,只需将其checked属性设置为false,例如

<input type=radio name=foo id=foo value=var>
<input type=button value="Uncheck" onclick=
"document.getElementById('foo').checked = false">

答案 2 :(得分:10)

包含在插件中

限制:

  1. 需要表单元素
  2. 以编程方式更改单选按钮时必须触发单击事件
  3. &#13;
    &#13;
    (function($) {
      $.fn.uncheckableRadio = function() {
        var $root = this;
        $root.each(function() {
          var $radio = $(this);
          if ($radio.prop('checked')) {
            $radio.data('checked', true);
          } else {
            $radio.data('checked', false);
          }
            
          $radio.click(function() {
            var $this = $(this);
            if ($this.data('checked')) {
              $this.prop('checked', false);
              $this.data('checked', false);
              $this.trigger('change');
            } else {
              $this.data('checked', true);
              $this.closest('form').find('[name="' + $this.prop('name') + '"]').not($this).data('checked', false);
            }
          });
        });
        return $root;
      };
    }(jQuery));
    
    $('[type=radio]').uncheckableRadio();
    $('button').click(function() {
      $('[value=V2]').prop('checked', true).trigger('change').trigger('click');
    });
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <form>
      <label><input name="myRadio" type="radio" value="V1" /> R1</label>
      <label><input name="myRadio" type="radio" value="V2" /> R2</label>
      <label><input name="myRadio" type="radio" value="V3" /> R3</label>
      <button type="button">Change R2</button>
    </form>
    &#13;
    &#13;
    &#13;

答案 3 :(得分:8)

这是我的答案(虽然我用jQuery制作但仅用于选择器并添加和删除一个类,所以你可以用纯JS选择器和纯JS添加属性轻松替换它)

    Name
1   Rob
2   Mark
3   Alex

答案 4 :(得分:7)

由于单选按钮主要用于组中,因此在脚本标记中getElementsByName( ' ' );更容易抓取它们。这将返回一个数组,在每个数组子上放置一个事件监听器并设置检查状态。看看这个样本。

var myRadios = document.getElementsByName('subscribe');
var setCheck;
var x = 0;
for(x = 0; x < myRadios.length; x++){

    myRadios[x].onclick = function(){
        if(setCheck != this){
             setCheck = this;
        }else{
            this.checked = false;
            setCheck = null;
    }
    };

}

This guide explain how the code works with a visual demonstration.

答案 5 :(得分:4)

取消选中无线电的工作原理(无效)

您无法轻松地通过if(this.checked) this.checked = false轻松地执行取消选中操作(如果您确实愿意,请参阅末尾的黑客方式),因为事件按以下顺序触发:

  1. mousedownkeydown
  2. mouseupkeyup
  3. 如果未选中,请立即设置选中的属性
  4. click
  5. input(仅当状态更改时)
  6. change(仅当状态更改时)

现在在哪个事件中执行所提到的取消选中状态?

  • mouseupmousedown:然后在步骤3中将该值重新设置为true并进行更改,并且输入事件甚至不会触发,因为按顺序调用它们时状态没有发生变化-所以您不能在这里取消选中它
  • click:然后状态始终为false,并且输入和更改也不会触发-因此您无法对其进行检查
  • inputchange:当状态未更改且单击所选元素不会更改状态时,它不会触发-因此您在这里无法做任何有用的事情

幼稚的方式

您可以从上面的序列中学到,方法是:

  1. 读取mouseup中的先前状态
  2. click中的状态设置为先前状态的否定

如果要将以前的状态存储在data属性中,请记住,该状态另存为 string ,而选中的属性为 boolean 。因此,您可以像这样实现它:

radio.onmouseup = function() { this.dataset.checked = this.checked? 1 : ""; }
radio.onclick = function() { this.checked = !this.dataset.checked; }

貌似可行,但由于以下原因,您不应该这样做:

  • 用户可以mousedown到其他地方,然后将鼠标悬停在单选按钮上方,然后再mouseup:在这种情况下,将触发mouseup并单击不会
  • 用户可以使用 Tab 聚焦广播组,然后使用箭头进行更改:mouseup不会触发,而单击会触发

正确的方法

还有另一个问题:动态添加的单选按钮。有两种方法:

  1. element.appendChild(radio)-如果在DOMContentLoaded事件中的所有无线电上启用取消选择,则此动态添加的无线电不受影响
  2. element.innerHTML+= '<input type="radio">'-有效替换元素的HTML内容并在其中重新创建DOM-因此所有事件侦听器都将被丢弃

要解决(2),我建议 onclick内容属性。请注意,element.onclick = fnelement.setAttribute("onclick", "fn()")是两件事。还要注意,onclick会在用户每次激活收音机时触发,无论使用何种界面。

另一个问题:如果启用取消选择功能,则还应该启用通过空格进行切换以模仿复选框行为。以下代码解决了所有提到的问题:

function deselectableRadios(rootElement) {
  if(!rootElement) rootElement = document;
  if(!window.radioChecked) window.radioChecked = null;
  window.radioClick = function(e) {
    const obj = e.target;
    if(e.keyCode) return obj.checked = e.keyCode!=32;
    obj.checked = window.radioChecked != obj;
    window.radioChecked = obj.checked ? obj : null;
  }
  rootElement.querySelectorAll("input[type='radio']").forEach( radio => {
    radio.setAttribute("onclick", "radioClick(event)");
    radio.setAttribute("onkeyup", "radioClick(event)");
  });
}

deselectableRadios();
<label><input type="radio" name="tag1">one</label>
<label><input type="radio" name="tag1">two</label>
<label><input type="radio" name="tag1">three</label>
<label><input type="radio" name="tag1">four</label>

现在,您可以在动态添加内容的任何时候致电deselectableRadios(),并且通过无线电多次调用不会破坏它。您还可以指定rootElement仅更新HTML DOM的子树,并使您的网站更快。如果您不喜欢全局状态,则可以使用黑客方式:

黑客方式

关键是要在设置选中的属性后滥用setTimeout上的mouseup来调用它:

function deselectable() {
  setTimeout(checked => this.checked = !checked, 0, this.checked);
}

现在您可以取消选择任何单选按钮:

radio.onmouseup = deselectable;

但是,这种简单的单线仅需单击即可使用,不能解决上述问题。

现代方式

可取消选中的单选框基本上是复选框,在该复选框中只能选中组中的一个。如果您的浏览器支持appearance CSS4功能,则只需

<input type="checkbox" name="foo" style="appearance: radio">

,然后在onclick事件getElementsByName("foo")中,取消选中名称的所有其余复选框(如果未选中复选框,则不会发送值)。

答案 6 :(得分:3)

我来到这里是因为我有同样的问题。我想向用户提供选项,同时保留为空的选项。虽然可以使用会使后端复杂化的复选框显式编码。

让用户使用Control + click几乎与让他们通过控制台取消选中它一样好。抓住mousedown是为了早点而且onclick为时已晚。

嗯,最后这是一个解决方案!只需将这几行放在页面上,就可以为页面上的所有单选按钮创建一行。你甚至可以摆弄选择器来定制它。

window.onload = function(){
document.querySelectorAll("INPUT[type='radio']").forEach(function(rd){rd.addEventListener("mousedown",
	function(){
		if (this.checked) {this.onclick=function(){this.checked=false}} else{this.onclick=null}
	})})}
<input type=radio name=unchecksample> Number One<br>
<input type=radio name=unchecksample> Number Two<br>
<input type=radio name=unchecksample> Number Three<br>
<input type=radio name=unchecksample> Number Four<br>
<input type=radio name=unchecksample> Number Five<br>

答案 7 :(得分:3)

虽然用javascript来询问,但jquery的改编是微不足道的...使用这种方法你可以检查“null”值并传递它......

var checked_val = "null";
$(".no_option").on("click", function(){
  if($(this).val() == checked_val){
  	$('input[name=group][value=null]').prop("checked",true);
    checked_val = "null";
  }else{
  	checked_val = $(this).val();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="radio" name="group" class="no_option" value="0">option 0<br>
<input type="radio" name="group" class="no_option" value="1">option 1<br>
<input type="radio" name="group" class="no_option" value="2">option 2<br>
<input type="radio" name="group" class="no_option" value="3">option 3<br>
<input type="radio" name="group" class="no_option" value="4">option 4<br>
<input type="radio" name="group" class="no_option" value="5">option 5<br>
<input type="radio" name="group" class="no_option" value="6">option 6<br>
<input type="radio" name="group" class="no_option" value="null" style="display:none">

答案 8 :(得分:1)

令我惊讶的是,没有人发布过这个“ 巧妙技巧”版本,该版本不使用任何JavaScript ,它仅使用CSS。

#radio1 {
    display: none;
}

#wrapper {
    /* NOTE: This wrapper div is not needed provided you can position the label for #radio1 on top of #radio2 using some other technique. */
    position: relative;
}

#radio1:not(:checked) ~ * label[for="radio1"] {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
#radio1:checked ~ * label[for="radio1"] {
    display: none;
}

/* Non-essential styles: */ 

label[for],
label:not([for="radio1"]) {
    cursor: pointer;
    border-radius: 7px;
}
label[for]:hover + label,
label:not([for="radio1"]):hover {
    background-color: #ccc;
}
<input type="radio" name="group1" id="radio1" checked="checked"  />

<p>Look mum, <strong>no JavaScript!</strong></p>

<div id="wrapper">
    <label for="radio1"></label>
    <label>
        <input type="radio" name="group1" id="radio2" />
        You can toggle me on and off!
    </label>
</div>


说明:

  • #radio1<input type="radio" id="radio2" />)始终是隐藏的。
  • 结合使用CSS的:checked:not(:checked)伪类选择器以及同级选择器(+~),可以根据是否使用其他元素来影响其他元素的样式<input type="checkbox" /><input type="radio" />被选中。
    • 因此,当{strong}取消选中#radio1时(或选中#radio2时),导致<label>覆盖在{{1 。
    • 重要注意事项:CSS的同级选择器规则仅允许选择器根据其祖先和祖先更早的兄弟姐妹来选择元素。因此,您不能根据元素祖先的 other 后代来设置元素的样式。
      • 当支持CSS4的#radio2选择器功能时,将消除此限制,但是从2020年11月开始,只有PrinceXML支持for="radio1",由于#radio1的出现,目前看来#radio2将从CSS4中完全删除实施难度。

此方法可以扩展为支持多个单选按钮:

:has()
:has()

答案 9 :(得分:1)

这就是我的意思:

function uncheck_radio_before_click(radio) {
    if(radio.prop('checked'))
        radio.one('click', function(){ radio.prop('checked', false); } );
}
$('body').on('mouseup', 'input[type="radio"]', function(){
    var radio=$(this);
    uncheck_radio_before_click(radio);
})
$('body').on('mouseup', 'label', function(){
    var label=$(this);
    var radio;
    if(label.attr('for'))
        radio=$('#'+label.attr('for')).filter('input[type="radio"]');
    else
        radio=label.children('input[type="radio"]');
    if(radio.length)
        uncheck_radio_before_click(radio);
})

http://jsfiddle.net/24vft2of/2/

答案 10 :(得分:1)

扩展user3716078的答案,允许多个独立的单选按钮组以及为多个元素分配事件监听器的更简洁的方式...

window.onload = function() {

    var acc_checked=[];

    [].slice.call(document.querySelectorAll('.accordion input[type="radio"]')).forEach(function(el,i){
        /**
         * i represents the integer value of where we are in the loop
         * el represents the element in question in the current loop
         */
        el.addEventListener('click', function(e){

            if(acc_checked[this.name] != this) {
                acc_checked[this.name] = this;
            } else {
                this.checked = false;
                acc_checked[this.name] = null;
            }

        }, false);

    });

}

答案 11 :(得分:1)

我将尝试通过3个单选按钮做出一个小小的答案,稍后您可以添加内容。

const radios = Array.from(document.getElementsByClassName('radio'))

for(let i of radios) {
    i.state = false

    i.onclick = () => {
        i.checked = i.state = !i.state

        for(let j of radios)
            if(j !== i) j.checked = j.state = false
    }
}
<input class="radio" type="radio">X
<input class="radio" type="radio">Y
<input class="radio" type="radio">Z
这适用于单一形式。如果您有多个带有class =“ radio”的表单,则单击单选按钮后,其他表单将被禁用。如果您要使用此功能。


现在,我想在我的rails项目中实现此功能,该项目具有多种形式(依赖关系,从数据库中获取),每种形式都有2个可见的单选按钮+ 1个隐藏的单选按钮。

我希望用户选择/取消选择每种形式的单选按钮。并且,在表单上选择一个按钮不应取消选择在另一表单上的另一个按钮。所以我宁愿这样做:

var radios = Array.from(document.getElementsByClassName('radio'))

for (let i of radios) {
  i.state = false

  i.onclick = () => {
    i.checked = i.state = !i.state

    for (let j of radios)
      if (j !== i) j.state = false
  }
}
<form>
  <input class="radio" name="A" type="radio">A
  <input class="radio" name="A" type="radio">B
  <input class="radio" name="A" type="radio">C
</form>

<form>
  <input class="radio" name="A" type="radio">D
  <input class="radio" name="A" type="radio">E
  <input class="radio" name="A" type="radio">F
</form>

<form>
  <input class="radio" name="SOMETHING" type="radio">G
  <input class="radio" name="SOMETHING" type="radio">H
  <input class="radio" name="SOMETHING" type="radio">I
</form>

您看到的所有名称都相同,但是格式不同(以3分组),因此适用于多种形式。

答案 12 :(得分:0)

我知道现在已经很晚了(甚至现在没有必要),这里有很多解决方案,但是我找不到针对所问问题的任何特定解决方案,或者对于这个简单的场景,其中有太多代码,可以轻松忽略它在寻找答案的同时。

所以在这里,我提出我的解决方案,因为它可能对任何新手都有帮助。思路很简单,就是

  • 在所需的切换上设置相同的类,在我的情况下是“切换”
  • 获取鼠标悬停时切换的当前值
  • 反转切换值。

通过这种方式,您可以选择任何切换或完全忽略它们,但再次单击已选择的切换。您还可以使用给定的代码段对此进行测试。

var val;
$('.toggles').mouseup(function(){
  val = this.checked
}).click(function(){
  this.checked = val == true ? false : true
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group">
    <input class="toggles form-check-input" type="radio" value="true" name="enabled" id="enabled_true">
    <label class="form-check-label" for="enabled_true">Enabled</label>
    <input class="toggles form-check-input" type="radio" value="false" name="enabled" id="enabled_false">
    <label class="form-check-label" for="enabled_false">Disabled</label>
</div>

答案 13 :(得分:0)

如果您正在jQuery中寻找解决方案,那就是。它类似于this

    $('input:radio').click(function() { 
      let name = $(this).attr('name');
      let self = $(this);
      [].filter.call($(`input[name=${name}]`), function(ele){
        return self[0] !== $(ele)[0];
      }).forEach(function(otherEle){
        $(otherEle).removeAttr('data-check');
      });

      if($(this).attr('data-check')){
        $(this).prop("checked", false);
        $(this).removeAttr('data-check');
      }else{
        $(this).attr("data-check", "1");
      }
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <input class="radio" name="A" type="radio">A
  <input class="radio" name="A" type="radio">B
  <input class="radio" name="A" type="radio">C
</form>

<form>
  <input class="radio" name="B" type="radio">D
  <input class="radio" name="B" type="radio">E
  <input class="radio" name="B" type="radio">F
</form>

<form>
  <input class="radio" name="C" type="radio">G
  <input class="radio" name="C" type="radio">H
  <input class="radio" name="C" type="radio">I
</form>

答案 14 :(得分:0)

这是普通JS的一种方式,它结合了onchangeonclick事件(onchange用于检查,onclick用于取消检查)。

document.querySelector("input").onchange = function() {
    this.onclick = function() {
        this.checked = false;
        this.onclick = null;
    }
};

答案 15 :(得分:0)

大多数现代浏览器都将checked="anything"视为checked="true"

如果您认为合适,则可能必须删除选中的属性,其中之一可能与加载页面有关。

$(this).removeAttr('checked')

在某些情况下希望检查单选按钮时可能会有所帮助。您只需删除属性即可实现。

PS:在所有情况下都无济于事。

答案 16 :(得分:0)

对Shmili Breuer答案的无错误更新。

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

        // update and remove the previous checked class
        var $prevChecked = $('input[name=' + $this.attr('name') + ']:not(:checked).checked');
            $prevChecked.removeClass('checked');

        if( $this.hasClass("checked") ) {
            $this.removeClass("checked");
            $this.prop("checked", false);
        }
        else {
            $this.addClass("checked");
        }
    });
})();

答案 17 :(得分:0)

古老的问题,但人们一直来自Google,OP最好不使用jQuery,所以这是我的镜头。

即使在IE 9上也应该可以使用

// iterate using Array method for compatibility
Array.prototype.forEach.call(document.querySelectorAll('[type=radio]'), function(radio) {
	radio.addEventListener('click', function(){
		var self = this;
		// get all elements with same name but itself and mark them unchecked
		Array.prototype.filter.call(document.getElementsByName(this.name), function(filterEl) {
			return self !== filterEl;
		}).forEach(function(otherEl) {
			delete otherEl.dataset.check
		})

		// set state based on previous one
		if (this.dataset.hasOwnProperty('check')) {
			this.checked = false
			delete this.dataset.check
		} else {
			this.dataset.check = ''
		}
	}, false)
})
<label><input type="radio" name="foo" value="1"/>foo = 1</label><br/>
<label><input type="radio" name="foo" value="2"/>foo = 2</label><br/>
<label><input type="radio" name="foo" value="3"/>foo = 3</label><br/>
<br/>
<label><input type="radio" name="bar" value="1"/>bar = 1</label><br/>
<label><input type="radio" name="bar" value="2"/>bar = 2</label><br/>
<label><input type="radio" name="bar" value="3"/>bar = 3</label><br/>

答案 18 :(得分:0)

纯JavaScript的完整示例:

    <label style='margin-right: 1em;' onmouseup='var temp = this.children[0]; if (temp.checked) { setTimeout(function() { temp.checked = false; }, 0); }'><input type='radio' name='chk_préf_méd_perso' value='valeur'>libellé</label>

答案 19 :(得分:0)

不幸的是,它不适用于Chrome或Edge,但适用于FireFox:

$(document)
// uncheck it when clicked
.on("click","input[type='radio']", function(){ $(this).prop("checked",false); })
// re-check it if value is changed to this input
.on("change","input[type='radio']", function(){ $(this).prop("checked",true); });

答案 20 :(得分:0)

如果你使用Iclick插入,就像你在下面看到的那样简单。

 $('#radio1').iCheck('uncheck');

答案 21 :(得分:0)

以下是一个示例,除了通过进行新选择之外,取消选中单选按钮是合适的。我有一本字典,可以使用各种索引选择条目。通过一组单选按钮选择使用哪个索引。但是,如果用户只想浏览,也可以使用“随机输入”按钮。通过随机输入按钮选择条目时保留索引会产生误导,因此当按下此按钮时,我取消选中所有索引选择单选按钮并用空页替换索引框的内容

答案 22 :(得分:0)

完整代码看起来像这样

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
<input name="radio" type="radio" id="myRadio" value="myRadio" checked="checked"     onclick="setRadio(this)" />
<label for="myRadio"></label>


<script language="javascript">
function setRadio(obj) 
{
    obj.checked = false;
}
</script>
</body>
</html>

答案 23 :(得分:0)

您可以使用单选按钮的checked属性取消选中它。

这样的事情:

<script>
 function uncheck()
 {
  document.getElementById('myRadio').checked = false;        
 }
 function check()
 {
  document.getElementById('myRadio').checked = true;        
 }
</script>
<input id="myRadio" type="radio" checked="checked"/>
<button onclick="uncheck();">Uncheck</button>
<button onclick="check();">Check</button>

在此处查看此行动:http://jsfiddle.net/wgYNa/

答案 24 :(得分:-1)

这几乎对我有用。

<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>

$(document).on("click", "input[name='radioBtn']", function(){
    thisRadio = $(this);
    if (thisRadio.hasClass("imChecked")) {
        thisRadio.removeClass("imChecked");
        thisRadio.prop('checked', false);
    } else { 
        thisRadio.prop('checked', true);
        thisRadio.addClass("imChecked");
    };
})

但是,如果我选中一个单选按钮,则选中另一个,然后再次尝试检查第一个,我必须单击两次。这是因为它具有类imChecked。我只需要在验证之前取消选中其他单选按钮即可。

添加此行使其起作用:

$(“ input [name ='radioBtn']”)。not(thisRadio).removeClass(“ imChecked”);

<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>

$(document).on("click", "input[name='radioBtn']", function(){
    thisRadio = $(this);
    $("input[name='radioBtn']").not(thisRadio).removeClass("imChecked");
    if (thisRadio.hasClass("imChecked")) {
        thisRadio.removeClass("imChecked");
        thisRadio.prop('checked', false);
    } else { 
        thisRadio.prop('checked', true);
        thisRadio.addClass("imChecked");
    };
})

答案 25 :(得分:-1)

下面的代码可以解决问题。

$('input[type=radio]').click(function() {
        if($(this).hasClass("checked")){
            this.checked = false;
            $(this).removeClass("checked")
        }else{
            $(this).addClass("checked")
        }
    });

答案 26 :(得分:-1)

让我们假设您有一个按钮,单击它可以将所有单选按钮选择都设置为false。您可以在onclick处理程序中编写以下代码。
下面的代码根据类名称使用单选按钮,对于每个元素,它将标记为false。

var elements=document.getElementsByClassName('Button');

Array.prototype.forEach.call(elements, function(element) {
  element.checked = false;
});