Javascript 使用javascript检查/取消选中无线电输入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6251719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
check/uncheck radio input with javascript
提问by NoOneElse
I have a radio input group. If a radio is checked and I click again it becomes unchecked.
我有一个收音机输入组。如果一个收音机被选中,我再次点击它变得未选中。
Is there a way to get the previous status of the radio onClick
event?
有没有办法获得无线电onClick
事件的先前状态?
<input name="options" type="radio" onClick="resetMeIfChecked()">
<input name="options" type="radio" onClick="resetMeIfChecked()">
<input name="options" type="radio" onClick="resetMeIfChecked()">
回答by mkilmanas
jQuery edition
jQuery 版
// bind to retrieve old status
$('input[type="radio"]').mousedown(function() {
// if it was checked before
if(this.checked) {
// bind event to reset state after click is completed
$(this).mouseup(function() {
// bind param, because "this" will point somewhere else in setTimeout
var radio = this;
// apparently if you do it immediatelly, it will be overriden, hence wait a tiny bit
setTimeout(function() {
radio.checked = false;
}, 5);
// don't handle mouseup anymore unless bound again
$(this).unbind('mouseup');
});
}
});
But again, this is not how radio buttons are intended to be used. I think you'd be better of with a set checkbox'es where you could uncheck all other checkboxes than the current clicked (hence always max 1 selected)
但同样,这不是单选按钮的使用方式。我认为您最好使用一组复选框,您可以在其中取消选中当前单击的所有其他复选框(因此始终最多选择 1 个)
回答by jerjer
try this:
尝试这个:
function resetMeIfChecked(radio){
if(radio.checked && radio.value == window.lastrv){
$(radio).removeAttr('checked');
window.lastrv = 0;
}
else
window.lastrv = radio.value;
}
<input value="1" name="options" checked="checked" type="radio" onClick="resetMeIfChecked(this)" />A
<input value="2" name="options" type="radio" onClick="resetMeIfChecked(this)" />B
<input value="3" name="options" type="radio" onClick="resetMeIfChecked(this)" />C
回答by JDGuide
Its quite simple. Just follow the simple example and
它很简单。只需按照简单的示例进行操作
var rdblength=document.formname.elementname.length;
alert('length='+rdblength);
for(i=0;i<rdblength;i++){
document.formname.elementname[i].checked=false;
}
Just find the length and make every index checked=true/false.
只需找到长度并使每个索引检查=真/假。
Ping me at:- http://manojbardhan2009.blogspot.com
Ping 我在:- http://manojbardhan2009.blogspot.com
回答by matewka
I had the same problem and figured it out. None of the answers above work exactly as I wanted - most of them require an additional button to reset the radio. The goal was to uncheck radio by clicking on the radio itself.
我有同样的问题并想通了。上面的答案都不是我想要的——大多数都需要一个额外的按钮来重置收音机。目标是通过单击收音机本身来取消选中收音机。
Here's the fiddle: http://jsfiddle.net/MEk5Q/1/
这是小提琴:http: //jsfiddle.net/MEk5Q/1/
The problem was very complicated because the radio button value changes BEFORE the click
event fires so when we're listening to the event we can't tell if the radio button was already checked or not. In both cases it is already checked.
Another approach was to listen to mousedown
event. Unlike click
, it fires before changing radio checked
attribute but unchecking it inside event handler gives us nothing since it is checked back again during mouseup event.
这个问题非常复杂,因为单选按钮的值在click
事件触发之前发生了变化,所以当我们侦听事件时,我们无法判断单选按钮是否已经被选中。在这两种情况下,它都已被检查。另一种方法是监听mousedown
事件。与 不同click
,它在更改 radiochecked
属性之前触发,但在事件处理程序中取消选中它不会给我们任何结果,因为它会在 mouseup 事件期间再次检查回来。
My answer is a little ugly workaround so I generally don't suggest it to others and I'll probably abandon it myself. It worksbut it involves 20ms timeout function which I'm not fond of in cases like this.
我的答案是一个有点丑陋的解决方法,所以我通常不会向其他人推荐它,我可能会自己放弃它。它有效,但它涉及 20ms 超时功能,在这种情况下我不喜欢。
Here is the code explanation:
下面是代码解释:
$('input[type="radio"]').on('mousedown', function() {
if (this.checked) { //on mousedown we can easily determine if the radio is already checked
this.dataset.check = '1'; //if so, we set a custom attribute (in DOM it would be data-check="1")
}
}).on('mouseup', function() {
if (this.dataset.check) { //then on mouseup we determine if the radio was just meant to be unchecked
var radio = this;
setTimeout(function() {radio.checked = false;}, 20); //we give it a 20ms delay because radio checking fires right after mouseup event
delete this.dataset.check; //get rid of our custom attribute
}
});
As a timeout function I could use a string (less writing) but as far as I know it would be eval
'ed. Though I don't trust eval
function, I prefered anonymous function.
作为超时函数,我可以使用字符串(较少写入),但据我所知它会被eval
'ed。虽然我不相信eval
函数,但我更喜欢匿名函数。
One more thing - one could ask why spreading the code into two separate event handlers while we can fire the timeout function on mousedown?Well, what if someone press the mouse on a radio and holds it for a few secs or even someone is simply a very slow person ;). Generally, with this solution we omit the problem of lag between mousedown
and mouseup
.
还有一件事 - 有人可能会问为什么将代码分散到两个单独的事件处理程序中,而我们可以在鼠标按下时触发超时功能?好吧,如果有人在收音机上按下鼠标并按住它几秒钟,或者甚至有人只是一个非常慢的人怎么办;)。通常,使用此解决方案,我们省略了mousedown
和之间的滞后问题mouseup
。
If you need some more info about dataset
, here's the MDN reference:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.datasetThis property came with HTML5 and might be not cross-browser, I guess, so if you want 100% compatibility, replace it with any other solution that'll contain the data, you name it.
如果您需要更多关于 的信息dataset
,这里是 MDN 参考:https:
//developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset此属性随 HTML5 一起提供,可能不是跨浏览器,我猜测,所以如果您想要 100% 兼容性,请将其替换为包含数据的任何其他解决方案,您可以命名它。
Sorry about jQuery here and there but I hope you're fine with it - it was much easier that way.
很抱歉这里和那里的 jQuery,但我希望你能接受它 - 这样更容易。
Hope you'll enjoy it.
希望你会喜欢。
回答by Argo
$('input[type="radio"]').on("mousedown", function () {
if (this.checked) {
$(this).one("click", function () {
this.checked = false;
});
}
});
回答by Harry Marx
I use this. You simply store the pre-click value and ! it into the value.
我用这个。您只需存储点击前值和 ! 它转化为价值。
<input type=radio name="myoptions" value="1"
onmousedown="this.tag = this.checked;" onclick="this.checked = !this.tag;">
回答by Bill Gradwohl
I was never too happy about being forced to aim at that tiny radio button, so I came up with a larger target AND a way to turn a radio group off without resorting to anything that would upset the HTML / JavaScript purists.
我从来没有因为被迫瞄准那个小单选按钮而高兴,所以我想出了一个更大的目标和一种关闭单选组的方法,而无需求助于任何会让 HTML/JavaScript 纯粹主义者感到不安的东西。
The technique relies on not molesting the radio buttons at all via event handlers, but checking for a readonly proxy for each one instead. Everything is contained in what's below in pure JavaScript using a radio group to select a type of cheese, or no cheese at all.
该技术完全不依赖于通过事件处理程序骚扰单选按钮,而是检查每个单选按钮的只读代理。一切都包含在下面的纯 JavaScript 中,使用无线电组来选择一种奶酪,或者根本不选择奶酪。
I purposely used no styling in this example to avoid that added layer. The dump button will tell you what the three checked states are, so use it to interrogate what happened after hitting the radio or text input elements. For example simplicity I used a global to remember the former state, but a more elegant method is to use a dataset, which I what I use in the real code of my application.
我故意在这个例子中没有使用样式来避免添加的层。转储按钮会告诉您三个选中状态是什么,因此可以使用它来查询点击收音机或文本输入元素后发生的情况。例如,我使用全局来记住前一个状态的简单性,但更优雅的方法是使用数据集,我在应用程序的实际代码中使用的数据集。
<!DOCTYPE html>
<html>
<head>
<title>Uncheck a radio button</title>
<script>
function attachEventListener(target, eventType, functionRef, capture) {
"use strict";
if (typeof target.addEventListener !== 'undefined') {
// Most modern browsers
target.addEventListener(eventType, functionRef, capture);
} else if (typeof target.attachEvent !== 'undefined') {
// IE
target.attachEvent('on' + eventType, functionRef);
} else {
eventType = 'on' + eventType;
if (typeof target[eventType] === 'function') {
var oldListener = target[eventType];
target[eventType] = function() {
oldListener();
return functionRef();
};
} else {
target[eventType] = functionRef;
}
}
}
</script>
</head>
<body>
<form>
<input id="Cheddar-radio" class="radio" type="radio" name="Cheeses-0" value="Cheddar Cheese" tabindex="-1"></input>
<input id="Cheddar-text" type="text" readonly value="Cheddar Cheese" tabindex="-1"></input><br>
<input id="Swiss-radio" class="radio" type="radio" name="Cheeses-0" value="Swiss Cheese" tabindex="-1"></input>
<input id="Swiss-text" type="text" readonly value="Swiss Cheese" tabindex="-1"></input><br>
<input id="American-radio" class="radio" type="radio" name="Cheeses-0" value="American Cheese" tabindex="-1"></input>
<input id="American-text" type="text" readonly value="American Cheese" tabindex="-1"></input><br><br>
<input onclick="dumpStates()" type="button" name="button" value="dump" tabindex="-1"></input>
</form>
<script>
window.onload = addRadioListeners;
function addRadioListeners() { // But do it on the -text elements.
attachEventListener(document.getElementById('Cheddar-text') , 'mousedown', rememberCurrentState, false);
attachEventListener(document.getElementById('Swiss-text') , 'mousedown', rememberCurrentState, false);
attachEventListener(document.getElementById('American-text'), 'mousedown', rememberCurrentState, false);
attachEventListener(document.getElementById('Cheddar-text') , 'mouseup', checkNewState, false);
attachEventListener(document.getElementById('Swiss-text') , 'mouseup', checkNewState, false);
attachEventListener(document.getElementById('American-text'), 'mouseup', checkNewState, false);
}
function dumpStates() {
console.log(document.getElementById('Cheddar-radio').checked +
' ' + document.getElementById('Swiss-radio').checked +
' ' + document.getElementById('American-radio').checked);
}
var elementWasChecked; // Global - Could just as well use a dataset attribute
// on either the -radio or -text element and check it instead.
function rememberCurrentState(event) {
var element;
var radioElement;
element = event.target;
radioElement = document.getElementById(element.id.replace(/text/,'radio'));
elementWasChecked = radioElement.checked;
radioElement.checked = true;
}
function checkNewState(event) {
var element;
var radioElement;
element = event.target;
radioElement = document.getElementById(element.id.replace(/text/,'radio'));
var currentState = radioElement.checked;
if (elementWasChecked === true && currentState === true) {
console.log('Changing ' + radioElement.id + ' to false.');
radioElement.checked = false;
}
};
</script>
</body>
</html>
If you click on the radio buttons they work as expected. If you click on the text items next to each, they are a proxy for the radio buttons with one exception. If you click on a text item that has an associated radio button that's already checked, it will uncheck it. Therefore, the text proxy's are event triggered, and not the radio buttons.
如果您单击单选按钮,它们会按预期工作。如果单击每个旁边的文本项,它们是单选按钮的代理,只有一个例外。如果您单击具有已选中的关联单选按钮的文本项,它将取消选中它。因此,文本代理是事件触发的,而不是单选按钮。
The added benefit is that you can now hit the larger text target too.
额外的好处是您现在也可以点击更大的文本目标。
回答by marcosfromero
This behavior is not the expected one for radio buttons and I don't recommend it at all. Try to find another way of achieving this. Use another widget or another option to reset the field value:
这种行为不是单选按钮的预期行为,我根本不推荐它。尝试找到实现这一目标的另一种方法。使用另一个小部件或另一个选项来重置字段值:
回答by Will Davies
If you want to make it simple and wouldn't mind using a double-click event try something like this:
如果您想让它变得简单并且不介意使用双击事件,请尝试以下操作:
<input name="options" type="radio" ondblclick="this.checked=false;">
回答by Jan Turoň
@jerjer's answer is almost perfect, but radios can be switched also by arrowsif the radio group has the focus (so mousedown event is not enough). Alas, the radio group also gets checked when activated by focus shift (Tab), which can undesirably check one option. Therefore spaceshould uncheck the focused radio, just like the checkbox behavior.
@jerjer 的回答几乎是完美的,但是arrows如果无线电组具有焦点,也可以切换无线电(因此 mousedown 事件是不够的)。唉,当通过焦点转移 ( Tab)激活时,无线电组也会被检查,这可能会不希望地检查一个选项。因此space应该取消选中重点收音机,就像复选框行为一样。
This code fixes that for all radios (Most credit still goes to jerjer):
此代码修复了所有收音机的问题(大部分功劳仍然归功于 jerjer):
window.addEventListener("DOMContentLoaded", function() {
var radios = document.querySelectorAll("input[type=radio]");
for(var i=0; i<radios.length; ++i) {
radios[i].addEventListener("click", function(e) {
if(e.target.checked && e.target.value == window.lastrv){
e.target.checked = false;
window.lastrv = 0;
}
else
window.lastrv = e.target.value;
});
radios[i].addEventListener("keypress", function(e) {
if(e.keyCode==32) e.target.click();
});
}
});