单选按钮 (INPUT type="radio") 的 OnChange 事件处理程序不能作为一个值工作

IT技术 javascript html cross-browser
2021-01-30 23:54:14

我正在为此寻找一个通用的解决方案。

考虑 2 个具有相同名称的无线电类型输入。提交时,被检查的那个决定了与表单一起发送的值:

<input type="radio" name="myRadios" onchange="handleChange1();" value="1" />
<input type="radio" name="myRadios" onchange="handleChange2();" value="2" />

取消选择单选按钮时不会触发更改事件。因此,如果已经选择了 value="1" 的收音机并且用户选择了第二个,handleChange1() 不会运行。这带来了一个问题(无论如何对我来说),因为我无法捕捉到这种取消选择的事件。

我想要的是复选框组值的 onchange 事件的解决方法,或者是一个 oncheck 事件,它不仅检测无线电何时被选中,而且何时被取消选中。

我相信你们中的一些人以前遇到过这个问题。有哪些解决方法(或者理想情况下处理此问题的正确方法是什么)?我只想捕捉更改事件,访问以前检查过的收音机以及新检查过的收音机。

PS
onclick 似乎是一个更好的(跨浏览器)事件来指示何时选中收音机,但它仍然不能解决未选中的问题。

我想为什么复选框类型的 onchange 在这样的情况下确实有效是有道理的,因为它会在您选中或取消选中它时更改它提交的值。我希望单选按钮的行为更像 SELECT 元素的 onchange 但你能做什么...

6个回答

var rad = document.myForm.myRadios;
var prev = null;
for (var i = 0; i < rad.length; i++) {
    rad[i].addEventListener('change', function() {
        (prev) ? console.log(prev.value): null;
        if (this !== prev) {
            prev = this;
        }
        console.log(this.value)
    });
}
<form name="myForm">
  <input type="radio" name="myRadios"  value="1" />
  <input type="radio" name="myRadios"  value="2" />
</form>

这是一个 JSFiddle 演示:https ://jsfiddle.net/crp6em1z/

最好在循环外缓存函数,以便所有无线电共享相同的事件处理程序(现在它们具有相同的处理程序,但它们是不同的功能)。或者也许将所有无线电放在一个包装器中并使用事件委托
2021-03-13 23:54:14
@Oriol 或任何知识渊博的人,您能否举一个示例(1)在循环外缓存或(2)包装器 + 事件委托?
2021-03-15 23:54:14
请注意为什么我选择它作为正确答案:单击事件处理程序设置在每个带有 name 属性的单选按钮上,myRadios以读取prev保存当前选定单选的变量在每个点击处理程序中进行比较,以确定被点击的收音机是否与存储在其中的收音机相同prev,如果不是,则将当前点击的收音机存储在那里。在点击处理程序中,您可以访问先前选择的:prev和当前选择的单选:this
2021-03-20 23:54:14
onclick 不适用于键盘选择,您可以使用rad[i].addEventListener('change', function(){ //your handler code })它,它适用于鼠标和键盘
2021-03-23 23:54:14
2021-04-02 23:54:14

我会做两个改变:

<input type="radio" name="myRadios" onclick="handleClick(this);" value="1" />
<input type="radio" name="myRadios" onclick="handleClick(this);" value="2" />
  1. 使用onclick处理程序而不是onchange- 您正在更改无线电输入的“已检查状态”,而不是value,因此不会发生更改事件。
  2. 使用单个函数,并this作为参数传递,这样可以轻松检查当前选择了哪个值。

ETA:与您的handleClick()功能一起,您可以在页面范围的变量中跟踪收音机的原始/旧值。那是:

var currentValue = 0;
function handleClick(myRadio) {
    alert('Old value: ' + currentValue);
    alert('New value: ' + myRadio.value);
    currentValue = myRadio.value;
}

var currentValue = 0;
function handleClick(myRadio) {
    alert('Old value: ' + currentValue);
    alert('New value: ' + myRadio.value);
    currentValue = myRadio.value;
}
<input type="radio" name="myRadios" onclick="handleClick(this);" value="1" />
<input type="radio" name="myRadios" onclick="handleClick(this);" value="2" />

+1。“onChange()”在 ReactJS 中不是可触发的事件,这是唯一的解决方案。来源:github.com/facebook/react/issues/1471
2021-03-12 23:54:14
如果用户使用键盘(tab + 空格键)选择收音机(这是大型表单的常见做法),“onClick”将不会处理该事件。
2021-03-22 23:54:14
谢谢,虽然这并没有解决必须获得以前检查过的收音机的问题,而且您还说明了其他用户已经提到的使用“onclick”而不是“onchange”的问题。我实际上从一开始就知道这一点,但我想提请注意这样一个事实,即 onchange 并不像人们预期的那样工作,我想更好地处理它。
2021-03-27 23:54:14
@Matthew:onclick处理程序只是命名不当——它处理单选按钮选择事件,无论按钮是单击、触摸还是通过在键盘上按“回车”键激活。onchange处理器没有在这种情况下,适当的,因为输入的值不会改变,只有选中/取消选中属性。我添加了一个示例脚本来解决以前的值。
2021-03-29 23:54:14
你在使用 JavaScript,对吧?那么为什么不只维护一个存储最后一个已知选择的单选按钮的变量呢?如果您使用的是单个处理程序,那么您可以在用新值覆盖它之前检查这个存储的值。+1
2021-04-02 23:54:14

正如你从这个例子中看到的:http : //jsfiddle.net/UTwGS/

HTML:

<label><input type="radio" value="1" name="my-radio">Radio One</label>
<label><input type="radio" value="2" name="my-radio">Radio One</label>

jQuery:

$('input[type="radio"]').on('click change', function(e) {
    console.log(e.type);
});

无论是clickchange选择(在一些浏览器至少)单选按钮选项,当事件被触发。

我还应该指出,在我的示例中,当您使用 Tab 和键盘选择一个选项时,click事件仍然会被触发

所以,我的观点是,即使change事件是由某些浏览器触发的,该click事件也应该提供您需要的覆盖范围。

但是您正在推广它 - 您的原始答案是“所以,我的观点是,即使触发了更改事件的是某些浏览器,单击事件也应提供您需要的覆盖范围作为后备,并且您可以在浏览器中使用更改支持它。” click是这里正确的处理程序,也是您唯一需要的处理程序。你的修订澄清了这一点,所以我要取消我的反对票。
2021-03-11 23:54:14
谢谢。但这并没有解决如何获取先前选择的复选框。也谢谢,我不知道 console.log 在 IE 中不起作用。
2021-03-19 23:54:14
不要在事件处理程序上加倍——在同时触发clickchange事件处理程序的浏览器中,您最终会调用处理程序两次。在这种情况下,由于@Matthew 关注的是先前的值,因此可能会导致不良后果。
2021-03-19 23:54:14
@NateCook 你显然没有理解我的例子。我展示了无论何时触发更改事件,都会触发单击事件。仅仅因为我在我的例子中使用了这两个事件并不意味着我在推广它。我认为你的反对票是不应该的。
2021-03-27 23:54:14
是的,因为console.log我的代码中有一个IE7 不支持语句。如果你愿意,你可以在 IE 中提醒它。
2021-04-08 23:54:14

使用jquery的change事件怎么样?

$(function() {
    $('input:radio[name="myRadios"]').change(function() {
        if ($(this).val() == '1') {
            alert("You selected the first option and deselected the second one");
        } else {
            alert("You selected the second option and deselected the first one");
        }
    });
});

jsfiddle:http : //jsfiddle.net/f8233x20/

$(this).val()也可以用原生 javascript 替换e.currentTarget.value,其中 e 是通过回调函数传递的事件对象。
2021-03-22 23:54:14
如果你为同一个收音机多次运行这个会发生什么?也许最好off打电话
2021-04-07 23:54:14

您可以添加以下JS脚本

<script>
    function myfunction(event) {
        alert('Checked radio with ID = ' + event.target.id);
    }
    document.querySelectorAll("input[name='myRadios']").forEach((input) => {
        input.addEventListener('change', myfunction);
    });
</script>