提问人:Richard Knop 提问时间:2/10/2011 更新时间:11/13/2022 访问量:117732
如何在点击时选中/取消选中单选按钮?
How to check/uncheck radio button on click?
问:
我希望能够通过单击取消选中单选按钮。
因此,如果取消选中单选按钮,我想检查它,如果选中,我想取消选中它。
这不起作用:
$('input[type=radio]:checked').click(function(){
$(this).attr('checked', false);
});
我现在无法检查单选按钮。
答:
如果只有一个单选按钮,则需要改用复选框。
拥有一个单选按钮是没有意义的,他们与组一起工作。
可能您正在寻找复选框控件。
评论
试试这个:
$('input[type=radio]').click(function(){
if (this.previous) {
this.checked = false;
}
this.previous = this.checked;
});
评论
这不是要替换复选框,而是要允许单选组返回到未选择的状态。这很棘手,因为无线电选择不像正常事件。
浏览器处理正常事件链之外的单选按钮。因此,带有 event.preventDefault() 或 event.stopPropagation() 的单选按钮上的单击处理程序不会阻止单选按钮被检查。必须在 setTimeout 中完成 .removeAttr('checked') 以允许事件完成,并且浏览器(再次)检查单选按钮,然后 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);
}
});
我希望这会有所帮助
评论
$self.bind('mouseup', up)
$self.mouseup(up)
$self.unbind('mouseup',up)
$self.off('mouseup')
$self.one('mouseup', up);
这才是真正的解决方案......
var check;
$('input[type="radio"]').hover(function() {
check = $(this).is(':checked');
});
$('input[type="radio"]').click(function() {
check = !check;
$(this).attr("checked", check);
});
试试吧,它对我有用!
评论
div
$('input[type="radio"]')
$('div.parentClass')
check = $(this).is(':checked');
check = $(this).find('input[type="radio"]').is(':checked');
var checked = {};
$('.desectable-radio').each(function (index) {
checked[index] = this.checked;
$(this).click(function () {
if (checked[index])
this.checked = false;
for (var i in checked) {
checked[i] = false;
}
checked[index] = this.checked;
});
});
在寻找解决方案时在某个地方找到了这个,喜欢它的简单性......
var checkedradio;
function docheck(thisradio) {
if (checkedradio == thisradio) {
thisradio.checked = false;
checkedradio = null;
}
else {checkedradio = thisradio;}
}
与以下设备一起使用:
<input type='radio' onclick='docheck(this);'>
不过,当您在一个表单中有多个单选按钮组时,似乎确实需要双击才能取消选择,但这可以通过为每个组设置一个功能来解决......
评论
checkedradio = (thisradio.checked &= checkedradio != thisradio) && thisradio
UX 最好有一个默认选择的“不选择”显式选项,并且不要让用户取消选中任何单选按钮。
(此nngroup(neilsen)文章中的列表项9:
http://www.nngroup.com/articles/checkboxes-vs-radio-buttons/
评论
下面是一个超轻量级脚本,您可以通过控制台窗口将其添加到页面中,该脚本允许您通过按住单选按钮并单击鼠标来取消选择该单选按钮。Ctrl
document.addEventListener('click', function(e){
if (e.ctrlKey == true &&
e.target.tagName == 'INPUT' &&
e.target.type == "radio" &&
e.target.checked == true) {
e.target.checked = false;
}
});
由于它不依赖于 jQuery,因此您可以轻松地将其添加到任何页面以暂时允许取消选择。
有关更多信息,您可以阅读我刚刚写的一篇关于如何取消选择单选按钮的文章。
接受的答案不适用于移动设备。它依赖于 setTimeout 和绑定,这些绑定与鼠标事件相关,这些事件不会在平板电脑/移动设备上触发。
我的解决方案是使用“click”事件处理程序和自定义类状态手动跟踪所选状态。
- 处理无线电输入元素上的单击事件
- 检查单击的元素上是否存在“Selected”类
- 如果是这样,(意味着它之前已被单击过),则删除该类并取消选中该元素,返回
- 如果没有,请从同名的所有元素中删除该类,并将其仅添加到单击的元素中。
无需阻止默认行为。下面是 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");
});
评论
我知道这个问题很老了,但我刚刚遇到这个问题并决定自己试一试,不想使用像 ctrl 这样的修饰键按钮。
在 http://jsfiddle.net/ArktekniK/yhbw469f/ 上看到小提琴 通过单击单选按钮本身来切换单选按钮
$('input[type=radio]').on('mousedown', function(e){
var wasChecked = $(this).prop('checked');
this.turnOff = wasChecked;
$(this).prop('checked', !wasChecked);
});
$('input[type=radio]').on('click', function(e){
$(this).prop('checked', !this.turnOff);
this['turning-off'] = !this.turnOff;
});
通过单击标签或单选按钮本身来切换单选按钮
$('label:has(input[type=radio])').on('mousedown', function(e){
var radio = $(this).find('input[type=radio]');
var wasChecked = radio.prop('checked');
radio[0].turnOff = wasChecked;
radio.prop('checked', !wasChecked);
});
$('label:has(input[type=radio])').on('click', function(e){
var radio = $(this).find('input[type=radio]');
radio.prop('checked', !radio[0].turnOff);
radio[0]['turning-off'] = !radio[0].turnOff;
});
评论
正如 HexInteractive 所提到的,单选按钮是在正常事件链之外处理的。 因此,以下示例通过类名而不是属性来判断按钮状态。
var $self;
$('input[type=radio]').on('click', function() {
$self = $(this);
if ( $self.hasClass('is-checked') ) {
$self.prop('checked', false).removeClass('is-checked');
} else {
$self.addClass('is-checked');
}
});
需要解决这个问题,我决定用“取消”图标按钮替换当前活动的单选按钮,如下所示 http://fontawesome.io/icon/ban/
单击此图标取消选中活动单选按钮,该按钮随后重新出现,有效地重置单选按钮组。取消图标也已从 DOM 中删除。
或者,用户可以单击组中的另一个单选按钮,除了取消按钮外,该按钮将正常运行,然后“移动”该按钮以替换新的活动单选按钮。
这样可以将取消图标保持在直观的位置(即用户上次单击的位置),并且比假设用户知道重新单击当前活动的单选按钮以停用组更安全。
最坏的情况是,如果您有一长串单选按钮,用户只需单击其中任何一个按钮两次即可清除该组。
评论
谁正在寻找纯 JavaScript 解决方案,我在 ATL 的回答中修改了 Jase 的代码。
我编写此代码是为了建议与 CSS 样式的 3 位开关一起使用,该开关提供 4 种切换状态(开、关、中性和未激活)。
function toggle_radio(ev) {
var radio = ev.target;
var cut_pos = radio.className.indexOf(' switcher-active');
// the switch itself
if (cut_pos !== -1) { // if the button checked it is '.switcher-active'
radio.checked = false; // toggle its state
radio.className = radio.className.slice(0, cut_pos); // remove '.switcher-active'
return true; // work is done. Break the function
}
// the button was inactive before it was clicked. Then it should became '.switcher-active'
radio.className = radio.className + ' switcher-active';
// we need to remove '.switcher-active' if either the left or right radio button was clicked. This part is uggly but I don't bother, because I'm late for barber
var radios = document.getElementsByName(radio.name); // get all these radio siblings as a collection of elements
for (var i=0; i < radios.length; i++) { // iterate through the collection
if (radios[i].className.indexOf('switcher-radio-neutral') !== -1)
continue; // skip the '.switcher-neutral' radio input
radios[i].onclick = function(ev2) {
sib_radios = document.getElementsByName(ev2.target.name); // get a group of radio inputs linked by the name
// get the '.switcher-neutral'
for (var k=0, cut_pos = -1, sib; k < sib_radios.length; k++) {
sib = sib_radios[k];
cut_pos = sib.className.indexOf(' switcher-active');
if (cut_pos !== -1)
sib.className = sib.className.slice(0, cut_pos);
}
}
}
}
var switchers = document.getElementsByClassName('switcher-radio-neutral');
for (var i=0; i < switchers.length; i++) { // bind onclick handlers
switchers[i].onclick = toggle_radio;
}
.switcher {
position: relative;
display: inline-block;
margin: 1px 10px;
height: 20px;
width: 58px;
z-index: 1;
}
.switcher-off {
left: 1px;
width: 33%;
height: 100%;
}
.switcher-neutral {
left: 33%;
width: 33%;
height: 100%;
}
.switcher-on{
right: 1px;
width: 33%;
height: 100%;
}
.switcher-label {
position: absolute;
text-indent: -9999px;
z-index: 2;
}
.switcher input {
visibility: hidden;
position: absolute;
}
.switcher-slider {
height: 100%;
width: 100%;
border-radius: 10px;
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1) inset, 0 0 4px rgba(0, 0, 0, 0.5) inset, 0 2px 2px 1px rgba(0, 0, 0, 0.3) inset;
transition: background-color 0.2s linear 0s;
}
.switcher-slider:after {
transition: left 0.2s linear 0s, right 0.2s linear 0s;
background: linear-gradient(#D0D0D0, #FDFDFD) repeat scroll 0 0 rgba(0, 0, 0, 0);
content: "";
position: absolute;
top: 1px;
border-radius: 50%;
height: calc(100% - 2px);
width: calc(100%/3 - 1px);
box-shadow: 0 0 1px 1px #f4f4f4 inset, 0 0 3px 1px rgba(0, 0, 0, 0.6);
left: 33%;
}
.switcher-radio-on:checked ~ .switcher-slider {
background-color: #81EA89;
}
.switcher-radio-neutral:checked ~ .switcher-slider {
background: #ddd;
}
.switcher-radio-off:checked ~ .switcher-slider {
background-color: #ED8282;
}
.switcher-radio-on:checked ~ .switcher-slider:after {
left: calc(2*(100%/3));
}
.switcher-radio-neutral:checked ~ .switcher-slider:after {
left: calc(1px + 100%/3);
}
.switcher-radio-off:checked ~ .switcher-slider:after {
left: 1px;
}
<form action="">
<input type="radio" name="radio_input" value="1">
<input type="radio" name="radio_input" class="switcher-radio-neutral" value="2">
<input type="radio" name="radio_input" value="3">
</form>
<br><br>
<div class="switcher">
<label class='switcher-label switcher-off' for='off'>off</label>
<input id='off' class='switcher-radio-off' type='radio' name='value' value='off'>
<label class='switcher-label switcher-neutral' for='neutral'>neutral</label>
<input id='neutral' class='switcher-radio-neutral' type='radio' name='value' value='neutral' data-neutral="">
<label class='switcher-label switcher-on' for='on'>on</label>
<input id='on' class='switcher-radio-on' type='radio' name='value' value='on'>
<div class='switcher-slider'></div>
</div>
我一定很想念它,但经过这么多年,AFAIK 上述解决方案似乎都不起作用,或者我只是愚蠢。
绝对没有理由使用单选按钮,除非同一组中有多个单选按钮。如果它是一个单独的单选按钮,那么只需使用一个复选框。使用单选按钮的原因是为了选择互斥选项之一。这意味着任何只查看单个按钮的解决方案都将失败,因为单击一个按钮将影响其他按钮的状态
换句话说,由于我们使用的是单发盒,因此该解决方案需要工作
<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>
根据 Stephen 的回答 - 这涉及多个单选按钮组,而且您大多不需要双击单选按钮。它并不完美,因为如果您在组之间切换,检查 id 将需要额外的点击,但工作正常。
$("input[type='radio']").on('click', function (e) {
if (this.previous && this.value == previousvalue && this.id == previousid) {
this.checked = false;
}
this.previous = this.checked;
previousvalue = this.value;
previousid = this.id;
});
我认为这是最短的路。我在 Chrome 和 MS Edge 上测试了它。
$(document).on('click', 'input:radio', function () {
var check = $(this).attr('checked')
if (check) $(this).removeAttr('checked').prop('checked',false)
else $(this).attr('checked', true).prop('checked',true)
})
这段代码也适用于 AJAX 加载的内容。
使用带有 checked 作为键的 prop 函数:
$("input:radio").prop("checked",false);
是的,您也可以在单击选中时执行此操作,再次单击取消选中。 这是其中的逻辑:
$('input[name=check1]').prop('checked',!$('input[name=check1]').prop('checked'));
这应该适用于桌面和移动设备。我在 Chrome 和 Firefox 上进行了测试。 基于评分最高的答案,但使用更新的 JQuery 和使用 $.one 的更简单的实现。
$(':radio').on("mousedown touchstart", function (e) {
var mobile = true;
if(e.type.toLowerCase() === 'mousedown'){
mobile = false;
}
var $self = $(this);
if($self.prop('checked')){
var uncheck = function(){
setTimeout(function(){
$self.prop('checked',false);
},10);
};
if(!mobile){
$self.one('mouseup', uncheck);
} else {
$self.one('touchstart', uncheck);
}
}
});
<script type="text/javascript">
$( document ).ready(function() {
$('input[type=radio]').click(function(){
if (this.previous) {
this.checked = false;
document.getElementById("nc").style.display = "block";
this.previous=false;
}
else {
this.previous = this.checked;
document.getElementById("nc").style.display = "none";
}
});
});
</script>
一个纯CSS解决方案(没有javascript)
label > input:checked,
label > input:checked + label {
pointer-events: none;
}
#unselect {
display: none;
}
<input type="radio" name="foo" id="unselect">
<label for="unselect">
<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>
</label>
单选按钮嵌入到另一个单选按钮中。 选择单选按钮后,它不再接受单击,而是基础单选按钮捕获单击。
https://jsfiddle.net/w29rem7q/
原始的、现已过时的解决方案
每个单选按钮都附加了一个虚拟单选按钮。如果选择了单选按钮,则单选按钮上方将出现一个不可见的虚拟人,以捕捉下一次单击。
input:not([id^=foo]) {
opacity: 0.0;
}
input[id^=foo]:checked {
position: absolute;
}
input[id^=foo]:not(:checked) + input {
display: none;
}
<input type="radio" name="foo" id="foo1">
<input type="radio" name="foo">
<label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2">
<input type="radio" name="foo">
<label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3">
<input type="radio" name="foo">
<label for="foo3">foo3</label>
可能只是为了好玩,而在实践中,js 会更容易维护。
此外,通过标签单击取消选择,将有更多的解决方法。
一个 javascript 版本,具有通过 和 无需双击取消选择的功能。
临时状态附加到父 div。for
label
Parent.onclick = e => {
rb = e.target;
if (rb.type == "radio") {
if (Parent.rb == rb) {
rb.checked = false;
Parent.rb = null;
} else {
Parent.rb = rb
}
}
}
<div id="Parent">
<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>
</div>
评论