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

Stu*_*ent 56 html javascript radio-button

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

Ten*_*eff 60

您可以将HTML对象的属性设置checkedfalse:

document.getElementById('desiredInput').checked = false;
Run Code Online (Sandbox Code Playgroud)

JavaScript示例

jQuery示例

PS:按住Ctrl键取消选中.

  • @pinkpanther,绝对不是.我认为这是解决这个问题的难题.删除`if ctrlKey`,并且......好吧,你可以取消选中它......但你永远不能检查收音机,因为[click] event-target的`checked`属性*将始终显示为checked*. (7认同)
  • 有没有办法判断一个特定的单选按钮是否已经被选中/为真,然后再次点击它,然后将其切换为取消选中/假,并使其成为文档中所有 type="radio" 元素的默认行为?我问是因为如果用户在平板电脑或触摸屏上,按住 CTRL 键不是很容易做到。 (3认同)
  • 这看起来就像我需要的那样,但是有什么方法可以不用按 Ctrl 来做到这一点?谢谢! (2认同)

Juk*_*ela 17

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

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

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

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

  • 如果您想要多个按钮作为一个组同时保持未选中的选项(或至少一个的视觉外观)怎么办?您的解决方案忽略了最终用户并要求基本上重写现有代码...... (5认同)

Jan*_*roň 15

取消选中收音机如何(不)工作

您无法通过if(this.checked) this.checked = false,轻松实现取消选中(如果您真的想要,请参阅最后的黑客方式),因为事件按以下顺序触发:

  1. mousedown 或者 keydown
  2. mouseup 或者 keyup
  3. 如果未选中,请立即设置选中的属性
  4. click
  5. input (仅当状态改变时)
  6. change (仅当状态改变时)

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

  • mouseupmousedown:然后在第 3 步中将值设置回 true 并且更改和输入事件甚至不会触发,因为在序列中调用它们时状态没有更改 - 所以你不能在这里取消选中它
  • click:那么状态总是假的,输入和更改也不会触发 - 所以你不能检查它
  • input或者change:当状态没有改变并且点击所选元素不会改变状态时它不会触发 - 所以你不能在这里做任何有用的事情

天真的方式

从上面的序列可以看出,方法是:

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

如果你想在 data 属性中存储之前的状态,记住它被保存为string,而被检查的属性是boolean。所以你可以像这样实现它:

radio.onmouseup = function() { this.dataset.checked = this.checked? 1 : ""; }
radio.onclick = function() { this.checked = !this.dataset.checked; }
Run Code Online (Sandbox Code Playgroud)

它似乎有效,但由于以下原因,您不应该这样做:

  • 用户可能会在mousedown其他地方,然后将鼠标悬停在单选按钮上方,然后mouseup:在这种情况下,mouseup 会触发,而 click 不会
  • 用户可以使用Tab聚焦无线电组,然后arrows更改:mouseup 不会触发,而 click 会

正确的方法

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

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

为了解决(2),我推荐onclick 内容属性。请注意,element.onclick = fnelement.setAttribute("onclick", "fn()")是两个不同的东西。另请注意onclick,无论用户使用何种接口,每次激活无线电时都会触发。

另一个问题:如果您启用取消选择,那么您还应该启用切换Space以模仿复选框行为。以下代码解决了所有提到的问题:

radio.onmouseup = function() { this.dataset.checked = this.checked? 1 : ""; }
radio.onclick = function() { this.checked = !this.dataset.checked; }
Run Code Online (Sandbox Code Playgroud)
function deselectableRadios(rootElement) {
  if(!rootElement) rootElement = document;
  if(!window.radioChecked) window.radioChecked = {};
  window.radioClick = function(e) {
    const obj = e.target, name = obj.name || "unnamed";
    if(e.keyCode) return obj.checked = e.keyCode!=32;
    obj.checked = window.radioChecked[name] != obj;
    window.radioChecked[name] = obj.checked ? obj : null;
  }
  rootElement.querySelectorAll("input[type='radio']").forEach( radio => {
    radio.setAttribute("onclick", "radioClick(event)");
    radio.setAttribute("onkeyup", "radioClick(event)");
  });
}

deselectableRadios();
Run Code Online (Sandbox Code Playgroud)

现在,您可以deselectableRadios()随时动态添加内容并在收音机上多次调用它并不会破坏它。您还可以指定rootElement只更新 HTML DOM 的子树,并使您的网络更快。如果不喜欢全局状态,可以使用hacker方式:

黑客之道

关键是setTimeoutmouseup设置了checked属性后滥用调用它:

function deselectable() {
  setTimeout(checked => this.checked = !checked, 0, this.checked);
}
Run Code Online (Sandbox Code Playgroud)

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

radio.onmouseup = deselectable;
Run Code Online (Sandbox Code Playgroud)

但是这个简单的单行只需要点击就可以工作,并不能解决上面提到的问题。

现代方式

可取消选择的收音机基本上是一个复选框,其中只能选中组中的一个。如果您的浏览器支持外观CSS4 功能,您可以简单地

<input type="checkbox" name="foo" style="appearance: radio">
Run Code Online (Sandbox Code Playgroud)

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

  • 这是唯一真正可行的解决方案 (2认同)

小智 12

包含在一个插件中

限制:

  1. 需要表单元素
  2. 以编程方式更改单选按钮时必须触发单击事件

(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');
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Shm*_*uer 11

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

<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");
    };
})
Run Code Online (Sandbox Code Playgroud)

  • 我花了大约三秒钟的时间才得出相同的(概念上的)答案。。。弄了个小提琴以表明它是有效的。想花时间做... [工作示例](https://jsfiddle.net/06zvu7eo/6/) (2认同)

小智 8

由于单选按钮主要用于组中,因此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;
    }
    };

}
Run Code Online (Sandbox Code Playgroud)

本指南解释了代码如何与视觉演示一起工作.

  • 该脚本完全不执行任何操作。`setCheck` 变量在这里没有任何意义。 (2认同)

me_*_*me_ 6

虽然它是在 javascript 方面被问到的,但 jquery 的适应是微不足道的......使用这种方法你可以检查“空”值并传递它......

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();
  }
});
Run Code Online (Sandbox Code Playgroud)
<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">
Run Code Online (Sandbox Code Playgroud)


Ped*_*ção 5

老问题,但人们一直从谷歌过来,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)
})
Run Code Online (Sandbox Code Playgroud)
<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/>
Run Code Online (Sandbox Code Playgroud)