Javascript 如何检测单选按钮取消选择事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11173685/
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
How to detect radio button deselect event?
提问by tskuzzy
Is there an easy way to attach a "deselect" event on a radio button? It seems that the change event only fires when the button is selected.
有没有一种简单的方法可以在单选按钮上附加“取消选择”事件?似乎只有在选择按钮时才会触发更改事件。
HTML
HTML
<input type="radio" id="one" name="a" />
<input type="radio" id="two" name="a" />
JavaScript
JavaScript
$('#one').change(function() {
if(this.checked) {
// do something when selected
} else { // THIS WILL NEVER HAPPEN
// do something when deselected
}
});?
采纳答案by brezanac
Why don't you simply create a custom event like, lets say, deselect
and let it trigger on all the members of the clicked radio group except the element itself that was clicked? Its way easier to make use of the event handling API that jQuery provides that way.
为什么不简单地创建一个自定义事件,比如说,deselect
让它在被点击的单选组的所有成员上触发,除了被点击的元素本身?它可以更轻松地使用 jQuery 提供的事件处理 API。
HTML
HTML
<!-- First group of radio buttons -->
<label for="btn_red">Red:</label><input id="btn_red" type="radio" name="radio_btn" />
<label for="btn_blue">Blue:</label><input id="btn_blue" type="radio" name="radio_btn" />
<label for="btn_yellow">Yellow:</label><input id="btn_yellow" type="radio" name="radio_btn" />
<label for="btn_pink">Pink:</label><input id="btn_pink" type="radio" name="radio_btn" />
<hr />
<!-- Second group of radio buttons -->
<label for="btn_red_group2">Red 2:</label><input id="btn_red_group2" type="radio" name="radio_btn_group2" />
<label for="btn_blue_group2">Blue 2:</label><input id="btn_blue_group2" type="radio" name="radio_btn_group2" />
<label for="btn_yellow_group2">Yellow 2:</label><input id="btn_yellow_group2" type="radio" name="radio_btn_group2" />
<label for="btn_pink_group2">Pink 2:</label><input id="btn_pink_group2" type="radio" name="radio_btn_group2" />
jQuery
jQuery
// Attaching click event handlers to all radio buttons...
$('input[type="radio"]').bind('click', function(){
// Processing only those that match the name attribute of the currently clicked button...
$('input[name="' + $(this).attr('name') + '"]').not($(this)).trigger('deselect'); // Every member of the current radio group except the clicked one...
});
$('input[type="radio"]').bind('deselect', function(){
console.log($(this));
})
?Deselection events will trigger only among members of the same radio group (elements that have the same name
attribute).
?Deselection 事件只会在同一无线电组的成员(具有相同name
属性的元素)之间触发。
EDIT:In order to account for all possible placements of the attached label tag (wrapping the radio element or being attached through an id selector) it is perhaps better to use onchange
event to trigger the handlers. Thanks to Faustfor pointing that out.
编辑:为了说明附加标签标签的所有可能位置(包装无线电元素或通过 id 选择器附加),最好使用onchange
事件来触发处理程序。感谢Faust指出这一点。
$('input[type="radio"]').on('change', function(){
// ...
}
回答by nnnnnn
You can create a custom "deselect" event relatively painlessly, but as you've already discovered the standard change event is only triggered on the newly checked radio button, not on the previously checked one that has just been unchecked.
您可以相对轻松地创建自定义“取消选择”事件,但正如您已经发现标准更改事件仅在新选中的单选按钮上触发,而不是在先前选中的刚刚取消选中的单选按钮上触发。
If you'd like to be able to say something like:
如果你想说的话:
$("#one").on("deselect", function() {
alert("Radio button one was just deselected");
});
Then run something like the following function from your document ready handler (or put the code directly in your document ready handler):
然后从您的文档就绪处理程序运行如下函数(或将代码直接放入您的文档就绪处理程序中):
function setupDeselectEvent() {
var selected = {};
$('input[type="radio"]').on('click', function() {
if (this.name in selected && this != selected[this.name])
$(selected[this.name]).trigger("deselect");
selected[this.name] = this;
}).filter(':checked').each(function() {
selected[this.name] = this;
});
}
Working demo:http://jsfiddle.net/s7f9s/2
工作演示:http : //jsfiddle.net/s7f9s/2
What this does is puts a click handler on all the radios on the page (this doesn't stop you adding your own click event handlers to the same radios) that will check if there was a previously selected radio in the same group (i.e., with the same name) and if so trigger a "deselect" event on thatradio. Then it saves the just-clicked one as the current one. The "deselect" event is not triggered if you click the already checked radio or if there was no previously checked one. The .filter().each()
bit at the end is to make note of which radios are alreadyselected. (If you need to cater for more than one form on the same page having independent radio groups of the same name then update the function above accordingly.)
这样做是在页面上的所有收音机上放置一个点击处理程序(这不会阻止您将自己的点击事件处理程序添加到相同的收音机中),它将检查同一组中是否存在先前选择的收音机(即,同名),如果是这样,则在该收音机上触发“取消选择”事件。然后它将刚刚点击的保存为当前的。如果您单击已选中的收音机或以前没有选中的收音机,则不会触发“取消选择”事件。最后的.filter().each()
位是记下已经选择了哪些收音机。(如果您需要在同一页面上处理多个具有同名独立广播组的表格,则相应地更新上述功能。)
回答by Tacroy
I found that the simplest way to do this without putting in a new framework to create a deselected
event, is to make changing anyradio button trigger an update
event on allof the radio buttons in its group and then define the behavior you want in the update event.
我发现在不放入新框架来创建deselected
事件的情况下执行此操作的最简单方法是更改任何单选按钮在其组中的所有单选按钮上触发update
事件,然后在更新事件中定义您想要的行为.
The downside is that the code in the deselection branch will run even if the radio button was not previously selected. If all you're doing is simple showing, hiding, or disabling UI elements, that shouldn't matter much.
缺点是即使单选按钮之前没有被选中,取消选择分支中的代码也会运行。如果您所做的只是简单地显示、隐藏或禁用 UI 元素,那应该没什么关系。
To use your example:
使用您的示例:
buttons = $('input[name="a"]');
buttons.change(function() {
buttons.trigger('update:groupA');
}).bind('update:groupA', function(){
if(this.checked) {
//Do your checked things
} else {
//Do your unchecked things. Gets called whenever any other button is selected, so don't toggle or do heavy computation in here.
}
});?
回答by Kamil Szot
You can trigger the 'change' event yourself. It's a bit tricky to avoid radio buttons infinitely triggering 'change' event on each other, but it can be done like this:
您可以自己触发“更改”事件。避免单选按钮无限触发彼此的“更改”事件有点棘手,但可以这样做:
$('input[type="radio"]').each(function() {
var name = $(this).attr('name');
var that = this;
$('input[name="'+name+'"][type="radio"]').not(that)
.on('change', function(e, alreadyTriggered) {
if(!alreadyTriggered || alreadyTriggered.indexOf(this) == -1) {
if(!alreadyTriggered) {
alreadyTriggered = [that];
}
alreadyTriggered.push(this);
$(that).trigger('change', [alreadyTriggered]);
}
});
});
Here's the demoof the above code at work.
这是上述代码在工作中的演示。
回答by Mauricio Moraes
I found a workaround for my specific casethat might help. This works when the "deselect" event can be applied to all radio buttons that aren't selected.
我为我的特定案例找到了可能有帮助的解决方法。当“取消选择”事件可以应用于所有未选中的单选按钮时,这会起作用。
I wanted to:
我想:
- add a classto the element when the radiobutton was selected, and
- remove that classwhen the button was "deselected".
- 选择单选按钮时向元素添加一个类,以及
- 当按钮被“取消选择”时删除该类。
I happened to find this question, because I had the same problem:
我碰巧找到了这个问题,因为我遇到了同样的问题:
$('input:radio').on('change', function() {
if( $(this).is(':checked') ) {
$(this).addClass('my-class-for-selected-buttons')
} else { // THIS WILL NEVER HAPPEN
$(this).removeClass('my-class-for-selected-buttons')
}
});?
But, in my case, the solution was pretty much easier, because I can try to remove the class from all the radio-buttons pretty simply with jQuery, and then add the class to the selected one:
但是,就我而言,解决方案要容易得多,因为我可以尝试使用 jQuery 非常简单地从所有单选按钮中删除该类,然后将该类添加到所选的类中:
$('input:radio').on('change', function() {
$('input:radio').removeClass('my-class-for-selected-buttons') // Here!
if( $(this).is(':checked') ) {
$(this).addClass('my-class-for-selected-buttons')
}
});?
With this simple tweak, I didn't need to find a way to trigger the "deselect" event.
通过这个简单的调整,我不需要找到触发“取消选择”事件的方法。
So, if in your case you can apply the event to all the radio buttons that aren't selected, and not only to the one that's just been "deselected", you can use this measure!
因此,如果在您的情况下,您可以将事件应用于所有未选中的单选按钮,而不仅仅是应用于刚刚“取消选中”的单选按钮,那么您可以使用此措施!
回答by Udo E.
Note:I'm using the most recent version of jquery: version 3.4.1. But this should work for older versions as well.
注意:我使用的是最新版本的 jquery:3.4.1 版。但这也适用于旧版本。
The major challenge here is that the change event is?only?triggered for the radio button that was checked. The code below confirms this.
这里的主要挑战是更改事件是什么?仅针对选中的单选按钮触发。下面的代码证实了这一点。
$("input[name^='account']").change(function() {
console.log($(this).prop('id') + " was checked");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<form action='#'>
<input id='john' type='radio' name='account[]' value=''><label for='john'>John</label><br>
<input id='jane' type='radio' name='account[]' value=''><label for='jane'>Jane</label><br>
<input id='jeff' type='radio' name='account[]' value=''><label for='jeff'>Jeff</label><br>
<input id='jude' type='radio' name='account[]' value=''><label for='jude'>Jude</label><br>
<input type='text' name='amount' value=''><br>
<input type='submit' value='submit'>
</form>
My Solution:Handle everything inside the change event handler in 3 simple steps:
我的解决方案:通过 3 个简单的步骤处理更改事件处理程序中的所有内容:
- handle the changes for the currently checked radio button.
- attach custom event and handler to all other radio buttons in the same group.
- immediately trigger this custom event.
- 处理当前选中的单选按钮的更改。
- 将自定义事件和处理程序附加到同一组中的所有其他单选按钮。
- 立即触发此自定义事件。
No need to play around with click events here. simple!
无需在此处处理点击事件。简单的!
var radioBtns = $("input[name^='account']");
radioBtns.change(function() {
// 1. handle changes for the currently checked radio button.
console.log($(this).prop('id') + " was checked");
// 2. attach custom event and handler to all other radio buttons in the same group.
radioBtns.not(':checked').off('deselect').on('deselect', function() {
$(this).each(function(i, e) {
console.log($(e).prop('id') + " was not checked");
});
}).trigger('deselect'); // 3. immediately trigger this custom event.
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<form action='#'>
<input id='john' type='radio' name='account[]' value=''><label for='john'>John</label><br>
<input id='jane' type='radio' name='account[]' value=''><label for='jane'>Jane</label><br>
<input id='jeff' type='radio' name='account[]' value=''><label for='jeff'>Jeff</label><br>
<input id='jude' type='radio' name='account[]' value=''><label for='jude'>Jude</label><br>
<input type='text' name='amount' value=''><br>
<input type='submit' value='submit'>
</form>
回答by elclanrs
I think this could be happening because the focus
event triggers before the change
event so the next radio you click will be focused before the previous checked radio triggers a change event. Don't quote me on this though...
我认为这可能发生,因为focus
事件在事件之前触发,change
因此您单击的下一个收音机将在上一个选中的收音机触发更改事件之前聚焦。不过不要引用我的话...
You could do it like this:
你可以这样做:
var isChecked = function(id) { alert(id + ': ' + $('#' + id).is(':checked')) }
$('input[name="a"]').change(function(){ isChecked('one') })
回答by David Cheung
I think you need to add the change function on the input level, rather than on each radio button.
我认为您需要在输入级别而不是每个单选按钮上添加更改功能。
Try this:
尝试这个:
$("input[name='a']").change(function() {
$("input[name='a']").each(function(){
if(this.checked) {
// do something when selected
} else {
// do something when deselected
}
});
});?
回答by Owen
hows this for ya?
这对你怎么样?
$('input').change(function() {
if ($('#one').is(':checked')) {
alert('checked');
} else {
alert('not checked');
}
});