如何检测单选按钮取消选择事件?

IT技术 javascript jquery
2021-03-21 10:32:52

有没有一种简单的方法可以在单选按钮上附加“取消选择”事件?似乎只有在选择按钮时才会触发更改事件。

HTML

<input type="radio" id="one" name="a" />
<input type="radio" id="two" name="a" />

JavaScript

$('#one').change(function() {
    if(this.checked) {
        // do something when selected
    } else { // THIS WILL NEVER HAPPEN
        // do something when deselected
    }
});​

的jsfiddle

6个回答

为什么不简单地创建一个自定义事件,比如说,deselect让它在被点击的单选组的所有成员上触发,除了被点击的元素本身?它可以更轻松地使用 jQuery 提供的事件处理 API。

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

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

取消选择事件只会在同一无线电组的成员(具有相同name属性的元素)之间触发

jsFiddle 解决方案

编辑:为了说明附加标签标签的所有可能位置(包装无线电元素或通过 id 选择器附加),最好使用onchange事件来触发处理程序。感谢Faust指出这一点。

$('input[type="radio"]').on('change', function(){
    // ...
}
如果收音机因为它的(非环绕)标签被点击而改变,则不会工作。
2021-04-27 10:32:52
+1。不错的解决方案,除了它没有指明之前选择了哪个收音机。
2021-05-13 10:32:52
我专注于这里的主要问题,即为自定义取消选择事件提供解决方案,但当然 OP 可以根据他/她的喜好修改它。
2021-05-13 10:32:52
绑定到更改事件而不是单击会更好。
2021-05-20 10:32:52
@Faust 您可以使用onchange无论标签是否包装都会触发事件。
2021-05-20 10:32:52

您可以相对轻松地创建自定义“取消选择”事件,但正如您已经发现标准更改事件仅在新选中的单选按钮上触发,而不是在先前选中的刚刚取消选中的单选按钮上触发。

如果你想说的话:

$("#one").on("deselect", function() {
    alert("Radio button one was just deselected");
});

然后从您的文档就绪处理程序运行如下函数(或将代码直接放入您的文档就绪处理程序中):

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

工作演示: http : //jsfiddle.net/s7f9s/2

这样做是在页面上的所有收音机上放置一个点击处理程序(这不会阻止您将自己的点击事件处理程序添加到相同的收音机中),它将检查同一组中是否存在先前选择的收音机(即,同名),如果是这样,则在收音机上触发“取消选择”事件然后它将刚刚单击的保存为当前的。如果您单击已选中的收音机或以前没有选中的收音机,则不会触发“取消选择”事件。最后的.filter().each()位是记下已经选择了哪些收音机(如果您需要在同一页面上处理多个具有同名独立广播组的表格,则相应地更新上述功能。)

+1 谢谢!!!这对我来说是完美的解决方案!我只需要将“on”函数调用更改为“bind”,因为我使用的是旧版本的 jQuery。
2021-04-22 10:32:52
绑定到更改事件而不是单击会更好。
2021-05-09 10:32:52
@KamilSzot - 不,不会。单击适用于所有浏览器,但在某些浏览器中,如果您通过键盘进行更改,则在您关闭控件之前不会发生更改事件。
2021-05-12 10:32:52
很棒的工作,但不幸的是这在 Mobile Safari 中不起作用。
2021-05-12 10:32:52

我发现在不放入新框架来创建deselected事件的情况下执行此操作的最简单方法是更改任何单选按钮在其组中的所有单选按钮上触发update事件,然后在更新事件中定义您想要的行为.

缺点是即使单选按钮之前没有被选中,取消选择分支中的代码也会运行。如果您所做的只是简单地显示、隐藏或禁用 UI 元素,那应该没什么关系。

使用您的示例:

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

我认为您需要在输入级别而不是在每个单选按钮上添加更改功能。

试试这个:

$("input[name='a']").change(function() {
  $("input[name='a']").each(function(){
    if(this.checked) {
        // do something when selected
    } else {
        // do something when deselected
    }
  });   
});​

我认为这可能发生,因为focus事件事件之前触发,change因此您单击的下一个收音机将在上一个选中的收音机触发更改事件之前聚焦。不过不要引用我的话...

你可以这样做:

var isChecked = function(id) { alert(id + ': ' + $('#' + id).is(':checked')) }
$('input[name="a"]').change(function(){ isChecked('one') })

演示: http : //jsfiddle.net/elclanrs/cD5ww/