61

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

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 ​</p>

4

10 回答 10

30

你为什么不简单地创建一个自定义事件,比如说,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事件来触发处理程序。感谢浮士德指出这一点。

$('input[type="radio"]').on('change', function(){
    // ...
}
于 2012-06-23T23:35:57.433 回答
23

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

如果您希望能够说类似的话:

$("#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()一点是记下已经选择了哪些收音机。(如果您需要在同一页面上处理多个具有相同名称的独立无线电组的表格,请相应地更新上述功能。)

于 2012-06-24T02:37:45.467 回答
4

我发现在不放入新框架来创建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.
    }
});​
于 2013-02-08T23:09:29.623 回答
2

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

试试这个:

$("input[name='a']").change(function() {
  $("input[name='a']").each(function(){
    if(this.checked) {
        // do something when selected
    } else {
        // do something when deselected
    }
  });   
});​
于 2012-06-24T02:55:18.040 回答
0

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

你可以这样做:

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

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

于 2012-06-23T23:38:02.113 回答
0

您可以自己触发“更改”事件。避免单选按钮无限触发彼此的“更改”事件有点棘手,但可以这样做:

$('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]);
            }
    });
});

这是上述代码在工作中的演示。

于 2014-03-26T13:58:42.793 回答
0

我为我的具体情况找到了一种可能有帮助的解决方法。当“取消选择”事件可以应用于所有未选中的单选按钮时,此方法有效。

我想:

  1. 选择单选按钮时向元素添加一个类,并且
  2. 当按钮被“取消选择”时删除该类

我碰巧找到了这个问题,因为我遇到了同样的问题:

$('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')
    }
});​

但是,在我的情况下,解决方案要容易得多,因为我可以尝试使用 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')
    }
});​

通过这个简单的调整,我不需要找到触发“取消选择”事件的方法。

因此,如果在您的情况下,您可以将事件应用于所有未选中的单选按钮,而不仅仅是刚刚“取消选择”的单选按钮,您可以使用此措施!

于 2015-12-06T22:49:28.257 回答
0

注意:我使用的是最新版本的 jquery:版本 3.4.1。但这也适用于旧版本。

这里的主要挑战是更改事件  针对已选中的单选按钮触发。下面的代码证实了这一点。

$("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>

我的解决方案:通过 3 个简单的步骤处理更改事件处理程序中的所有内容:

  1. 处理当前选中的单选按钮的更改。
  2. 将自定义事件和处理程序附加到同一组中的所有其他单选按钮。
  3. 立即触发此自定义事件。

无需在这里玩点击事件。简单的!

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>

于 2019-12-30T18:43:08.357 回答
0

我玩了一下ids。公平地说,这可能是一个低效的解决方案。

<input type="radio" id="radio-1" name="a" value="initial 1"/>
<input type="radio" id="radio-2" name="a" value="initial 2"/>
let id;
$('input[id*="radio-"]').on('click', (function() {
      if (this.id != id && this.checked) {
        id = this.id;
        this.checked = true;
        console.log('selected');
      } else if (this.id == id && this.checked) {
        id = undefined;
        this.checked = false;
        console.log('deselected');
      }
}));

JSFiddle

于 2021-05-21T16:07:19.793 回答
-1

这对你怎么样?

http://jsfiddle.net/WZND9/6/

 $('input').change(function() {
    if ($('#one').is(':checked')) {
        alert('checked');
    } else { 
        alert('not checked');
    }
 }); 
于 2012-06-23T23:32:12.630 回答