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

时间:2011-02-10 12:41:25

标签: javascript jquery

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

因此,如果未选中单选按钮,我想检查它,如果选中它,我想取消选中它。

这不起作用:

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

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

20 个答案:

答案 0 :(得分:67)

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

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

这也正确处理了用户启动mousedown但在mouseup之前离开radiobutton的情况。

//$ = 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);
  }
});

我希望这会有所帮助

答案 1 :(得分:12)

试试这个:

$('input[type=radio]').click(function(){
    if (this.previous) {
        this.checked = false;
    }
    this.previous = this.checked;
});

答案 2 :(得分:8)

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

  1. 处理无线电输入元素上的点击事件
  2. 检查"选择"类存在于被点击的元素
  3. 如果是,(意味着之前已点击过),请删除该类并取消选中该元素,返回
  4. 如果没有,请从同名的所有元素中删除该类,并将其添加到所单击的元素中。
  5. 无需阻止默认行为。这是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/

答案 3 :(得分:3)

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

var check;

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

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

尝试一下,它对我有用!

答案 4 :(得分:2)

拥有默认选择的“Select none”显式选项是最好的UX,不要让用户取消选中任何单选按钮。

(在此nngroup(neilsen)文章中列出第9项:

http://www.nngroup.com/articles/checkboxes-vs-radio-buttons/

答案 5 :(得分:2)

如果只有一个单选按钮,则需要使用复选框。

他们使用一个单选按钮没有任何意义。

可能你正在寻找复选框控制。

答案 6 :(得分:2)

我知道这个问题很老,但我刚遇到这个问题并且决定自己动手并且不想使用像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;
});

答案 7 :(得分:1)

正如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');
  }
});

答案 8 :(得分:1)

是的,您还可以在选中后执行此操作,然后再次单击取消选中。 这是逻辑:

$('input[name=check1]').prop('checked',!$('input[name=check1]').prop('checked'));

答案 9 :(得分:1)

谁在寻找纯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>

答案 10 :(得分:0)

这是一个超级轻量级​​脚本,您可以通过控制台窗口添加到页面,允许您通过按住 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,您可以轻松地将其添加到任何页面以暂时允许取消选择 有关详细信息,您可以阅读我刚刚在How To Deselect A Radio Button上撰写的文章。

答案 11 :(得分:0)

需要解决此问题的方法,我决定用“取消”图标按钮替换当前活动的单选按钮,如http://fontawesome.io/icon/ban/

单击此图标取消选中当前重新出现的活动单选按钮,有效地重置单选按钮组。取消图标也已从DOM中删除。

或者,用户可以单击该组中的另一个单选按钮,除了取消按钮之外,该按钮会正常运行,然后“移动”以替换新的活动单选按钮。

这使得取消图标保持在一个直观的位置(即用户最后点击的位置),并且比假设用户知道重新点击当前活动的单选按钮以停用该组更安全。

最糟糕的情况是,如果你有一长串单选按钮,用户只需要点击其中任何一个以清除该组。

答案 12 :(得分:0)

在寻找解决方案的同时找到了这个,就像它的简单......

var checkedradio;
function docheck(thisradio) {
    if (checkedradio == thisradio) {
        thisradio.checked = false;
        checkedradio = null;
    }
    else {checkedradio = thisradio;}
}

使用:

<input type='radio' onclick='docheck(this);'>

当你在一个表单中有多个无线电组时,似乎需要双击才能取消选择,但是这可以通过为每个组设置一个函数来解决...我猜想...

答案 13 :(得分:0)

我一定很想念它,但是在所有这些年之后的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>

答案 14 :(得分:0)

根据斯蒂芬的回答-这涉及多个单选按钮组,而且您通常不需要双击单选按钮。这不是一个完美的选择,因为如果您要在组之间进行切换,则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;

        });

答案 15 :(得分:0)

我认为这是最短的方法。我在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加载的内容

答案 16 :(得分:0)

使用 prop 功能并选中作为键:

$("input:radio").prop("checked",false);

答案 17 :(得分:0)

 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;
        });
    });

答案 18 :(得分:0)

这应该适用于桌面和移动设备。我在 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);
        }
    }
});

答案 19 :(得分:0)

<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>