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

Mat*_*hew 169 html javascript cross-browser

我正在寻找一个通用的解决方案.

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

<input type="radio" name="myRadios" onchange="handleChange1();" value="1" />
<input type="radio" name="myRadios" onchange="handleChange2();" value="2" />
Run Code Online (Sandbox Code Playgroud)

取消选择单选按钮时,不会触发更改事件.因此,如果已选择值为"1"的无线电并且用户选择第二个,则handleChange1()不会运行.这给我带来了一个问题(对我来说无论如何),因为没有任何事情我可以捕捉到这种取消选择.

我想要的是复选框组值的onchange事件的解决方法,或者是一个oncheck事件,它不仅检测收音机何时被检查,还检测未选中的时间.

我相信你们中的一些人之前遇到过这个问题.有哪些解决方法(或理想情况下处理此问题的正确方法)?我只是想捕捉改变事件,访问先前检查的无线电以及新检查的无线电.

PS
onclick似乎是一个更好的(跨浏览器)事件来指示何时检查无线电但它仍然无法解决未检查的问题.

我认为为什么onchange for checkbox类型在这种情况下工作是有道理的,因为它会更改它在检查或取消选中时提交的值.我希望单选按钮的行为更像是SELECT元素的onchange但是你能做什么......

Mic*_*hal 160

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)
    });
}
Run Code Online (Sandbox Code Playgroud)
<form name="myForm">
  <input type="radio" name="myRadios"  value="1" />
  <input type="radio" name="myRadios"  value="2" />
</form>
Run Code Online (Sandbox Code Playgroud)

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

  • 最好将函数缓存在循环外部,以便所有无线电共享相同的事件处理程序(现在它们具有相同的处理程序,但它们是不同的函数).或者将所有无线电放入包装器中并使用事件委托 (23认同)
  • onclick不能用于键盘选择,你可以使用`rad [i] .addEventListener('change',function(){//你的处理程序代码})`它可以用于鼠标和键盘 (12认同)
  • @MattVoda [没有优化](https://jsfiddle.net/f67a9ua7/).[分享事件监听器](https://jsfiddle.net/f67a9ua7/1/).[有事件委托](https://jsfiddle.net/f67a9ua7/2/) (9认同)
  • 请注意为什么我选择这个作为正确答案:在名称属性为"myRadios"的每个单选按钮上设置Click事件处理程序,以读取保存当前所选无线电的变量"prev".在每个点击处理程序中进行比较,以确定点击的无线电是否与存储在"prev"中的无线电相同,如果没有则将当前点击的无线电存储在那里.在点击处理程序中,您可以访问先前选择的:`prev`和当前选择的无线电:`this` (4认同)
  • @Oriol 或任何知识渊博的人,您能否举一个示例(1)在循环外缓存或(2)包装器 + 事件委托? (2认同)
  • @MattVoda我不会使用第一个,因为我认为复制每个元素的事件侦听器没有任何优势。第二个与第一个类似,但所有元素共享相同的事件侦听器。第三个将事件侦听器添加到单个元素,但是每次触发事件时,您都必须检查目标,如果中间的某个元素停止事件的传播,侦听器将不会运行。当动态插入新元素时,第三个很有用,否则第二个更简单。 (2认同)

Nat*_*ook 102

我会做两个改变:

<input type="radio" name="myRadios" onclick="handleClick(this);" value="1" />
<input type="radio" name="myRadios" onclick="handleClick(this);" value="2" />
Run Code Online (Sandbox Code Playgroud)
  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;
}
Run Code Online (Sandbox Code Playgroud)

  • @Matthew:`onclick`处理程序命名不佳 - 它处理单选按钮选择事件,无论是通过点击键盘上的"输入"单击,触摸还是激活按钮.在这种情况下,`onchange`处理程序是不合适的,因为输入的值不会改变,只有checked/unchecked属性.我添加了一个示例脚本来解决以前的值. (10认同)
  • 如果用户使用键盘(tab + 空格键)选择收音机(这是大型表单的常见做法),“onClick”将不会处理该事件。 (2认同)

Phi*_*ton 36

从这个例子可以看出: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>
Run Code Online (Sandbox Code Playgroud)

jQuery的:

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

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

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

所以,我的观点是,即使change事件被触发是一些浏览器,click事件应该提供您需要的覆盖.

  • 是的,因为我的代码中有一个`console.log`语句,IE7不支持.如果你愿意,你可以在IE中提醒它. (6认同)
  • @NateCook你明显错过了我的例子.我表示,无论何时触发更改事件,都会触发click事件.仅仅因为我在我的例子中使用这两个事件并不意味着我正在推广它.我认为你的投票不值得. (2认同)

Buz*_*uzz 9

您可以添加以下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>
Run Code Online (Sandbox Code Playgroud)


Bal*_*aji 9

最简单、最强大的方式

使用 getAttribute 只读无线电输入

document.addEventListener('input',(e)=>{

if(e.target.getAttribute('name')=="myRadios")
console.log(e.target.value)
})
Run Code Online (Sandbox Code Playgroud)
<input type="radio" name="myRadios" value="1" /> 1
<input type="radio" name="myRadios" value="2" /> 2
Run Code Online (Sandbox Code Playgroud)


Ale*_*hko 6

我不认为除了存储以前的状态之外还有其他方法.这是jQuery的解决方案

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
<script type="text/javascript">
    var lastSelected;
    $(function () {
        //if you have any radio selected by default
        lastSelected = $('[name="myRadios"]:checked').val();
    });
    $(document).on('click', '[name="myRadios"]', function () {
        if (lastSelected != $(this).val() && typeof lastSelected != "undefined") {
            alert("radio box with value " + $('[name="myRadios"][value="' + lastSelected + '"]').val() + " was deselected");
        }
        lastSelected = $(this).val();
    });
</script>

<input type="radio" name="myRadios" value="1" />
<input type="radio" name="myRadios" value="2" />
<input type="radio" name="myRadios" value="3" />
<input type="radio" name="myRadios" value="4" />
<input type="radio" name="myRadios" value="5" />
Run Code Online (Sandbox Code Playgroud)

在考虑了一下之后,我决定摆脱变量并添加/删除类.这是我得到的:http://jsfiddle.net/BeQh3/2/


Raz*_*aul 6

使用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");
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

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


Con*_*roß 5

正如您在此处看到的:http : //www.w3schools.com/jsref/event_onchange.asp 单选按钮不支持 onchange 属性。

您链接的第一个 SO 问题为您提供了答案:改用onclick事件并检查它触发的函数内的单选按钮状态。

  • `onclick` 不是相同的语义,因为在启用键盘表单选择的情况下,您可以通过键盘输入更改单选按钮的选中状态。 (2认同)

Dio*_*ode 5

是的,当前选定的单选按钮没有更改事件。但问题是当每个单选按钮都被视为一个单独的元素时。相反,无线电组应被视为单个元素,例如select. 因此为该组触发更改事件。如果它是一个select元素,我们从不关心其中的每个选项,而只考虑选定的选项。We store the current value in a variable which will become the previous value, when a new option is selected. 同样,您必须使用单独的变量来存储选中单选按钮的值。

如果要识别上一个单选按钮,则必须在mousedown事件上循环。

var radios = document.getElementsByName("myRadios");
var val;
for(var i = 0; i < radios.length; i++){
    if(radios[i].checked){
        val = radios[i].value;
    }
}
Run Code Online (Sandbox Code Playgroud)

看到这个:http : //jsfiddle.net/diode/tywx6/2/


Dim*_*nev 5

将先前检查的单选存储在变量中:http :
//jsfiddle.net/dsbonev/C5S4B/

的HTML

<input type="radio" name="myRadios" value="1" /> 1
<input type="radio" name="myRadios" value="2" /> 2
<input type="radio" name="myRadios" value="3" /> 3
<input type="radio" name="myRadios" value="4" /> 4
<input type="radio" name="myRadios" value="5" /> 5
Run Code Online (Sandbox Code Playgroud)

JS

var changeHandler = (function initChangeHandler() {
    var previousCheckedRadio = null;

    var result = function (event) {
        var currentCheckedRadio = event.target;
        var name = currentCheckedRadio.name;

        if (name !== 'myRadios') return;

        //using radio elements previousCheckedRadio and currentCheckedRadio

        //storing radio element for using in future 'change' event handler
        previousCheckedRadio = currentCheckedRadio;
    };

    return result;
})();

document.addEventListener('change', changeHandler, false);
Run Code Online (Sandbox Code Playgroud)

JS示例代码

var changeHandler = (function initChangeHandler() {
    var previousCheckedRadio = null;

    function logInfo(info) {
        if (!console || !console.log) return;

        console.log(info);
    }

    function logPrevious(element) {
        if (!element) return;

        var message = element.value + ' was unchecked';

        logInfo(message);
    }

    function logCurrent(element) {
        if (!element) return;

        var message = element.value + ' is checked';

        logInfo(message);
    }

    var result = function (event) {
        var currentCheckedRadio = event.target;
        var name = currentCheckedRadio.name;

        if (name !== 'myRadios') return;

        logPrevious(previousCheckedRadio);
        logCurrent(currentCheckedRadio);

        previousCheckedRadio = currentCheckedRadio;
    };

    return result;
})();

document.addEventListener('change', changeHandler, false);
Run Code Online (Sandbox Code Playgroud)


小智 5

我意识到这是一个老问题,但这段代码对我有用.也许未来有人会发现它很有用:

<h2>Testing radio functionality</h2>
<script type="text/javascript">var radioArray=[null];</script>
<input name="juju" value="button1" type="radio" onclick="radioChange('juju','button1',radioArray);" />Button 1
<input name="juju" value="button2" type="radio" onclick="radioChange('juju','button2',radioArray);" />Button 2
<input name="juju" value="button3" type="radio" onclick="radioChange('juju','button3',radioArray);" />Button 3
<br />

<script type="text/javascript">
function radioChange(radioSet,radioButton,radioArray)
  {
  //if(radioArray instanceof Array) {alert('Array Passed');}
  var oldButton=radioArray[0];
  if(radioArray[0] == null)
    {
    alert('Old button was not defined');
    radioArray[0]=radioButton;
    }
  else
    {
    alert('Old button was set to ' + oldButton);
    radioArray[0]=radioButton;
    }
  alert('New button is set to ' + radioArray[0]);
  }
</script>
Run Code Online (Sandbox Code Playgroud)