ラジオボタン(INPUT type =“ radio”)のOnChangeイベントハンドラーが1つの値として機能しない


190

これに対する一般的な解決策を探しています。

同じ名前の2つの無線タイプ入力があるとします。送信されると、チェックされるものがフォームで送信される値を決定します。

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

ラジオボタンの選択が解除されている場合、変更イベントは発生しません。したがって、value = "1"のラジオがすでに選択されていて、ユーザーが2番目を選択した場合、handleChange1()は実行されません。これは、(とにかく私にとって)この選択解除をキャッチできるイベントがないという問題を提起します。

私が欲しいのは、チェックボックスグループ値のonchangeイベント、またはラジオがチェックされているときだけでなくチェックされていないときも検出するoncheckイベントの回避策です。

あなた方の何人かは以前にこの問題に遭遇したと思います。いくつかの回避策はありますか(理想的にはこれを処理する正しい方法は何ですか)?変更イベントをキャッチし、以前にチェックしたラジオと新しくチェックしたラジオにアクセスしたいだけです。

PS
onclickは、ラジオがチェックされたときを示すための(クロスブラウザーの)より良いイベントのように見えますが、チェックされていない問題を解決しません。

このような場合、チェックボックスタイプのonchangeが機能する理由は、チェックしたりチェックを外したりするときに送信される値を変更するため、理にかなっていると思います。ラジオボタンがSELECT要素のonchangeのように動作することを望みますが、何ができますか...

回答:


179

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/


4
これを正解として選択した理由についてのメモ:現在選択されているラジオを保持するmyRadios変数prevを読み取るために、name属性を持つ各ラジオボタンにクリックイベントハンドラーが設定されています。各クリックハンドラー内で比較が行われ、クリックされたラジオが保存されているラジオと同じかどうかが判断されprev、そうでない場合、現在クリックされているラジオがそこに保存されます。:クリックハンドラ内では、以前に選択へのアクセス持っているprevと、現在選択されているラジオを:this
マシュー

26
すべての無線機が同じイベントハンドラーを共有するように、関数をループの外側にキャッシュすることをお勧めします(これらの無線機は同じハンドラーを持っていますが、関数は異なります)。または、すべての無線機をラッパー内に配置し、イベントの委任を使用する
Oriol 2013

1
@Oriol、または知識のある人なら、(1)ループ外のキャッシュ、または(2)ラッパー+イベントの委譲の例を挙げていただけますか?
Matt Voda


14
onclickはキーボード選択では機能せず、使用できrad[i].addEventListener('change', function(){ //your handler code })、マウスとキーボードの両方で機能します
Juanmi Rodriguez

117

2つの変更を行います。

<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" />


おかげで、これは以前にチェックされたラジオを取得する必要があるという問題に対処していません。また、「onchange」の代わりに「onclick」を使用することを他のユーザーがすでに述べていることも述べています。私は実際にこれを最初から知っていましたが、onchangeが期待どおりに機能しないことと、より適切に処理したいという事実に注目したいと思いました。
マシュー

1
JavaScriptを使用していますよね?それでは、なぜ最後に選択されたラジオボタンを格納する変数を維持しないのでしょうか。単一のハンドラーを使用している場合は、新しい値で上書きする前に、この格納された値を確認できます。+1
jmort253 2012年

13
@Matthew:onclickハンドラーの名前は不適切です-キーボードで「Enter」を押してボタンがクリック、タッチ、またはアクティブ化されたかどうかに関係なく、ラジオボタン選択のイベントを処理します。onchangeハンドラにのみチェック/未チェックの属性を、入力の値が変化しないため、この場合には適切ではありません。以前の値に対処するためにサンプルスクリプトを追加しました。
ネイトクック

1
ユーザーがキーボード(タブ+スペースバー)を使用してラジオを選択した場合、「onClick」はイベントを処理しません(これは大きなフォームでは一般的な方法です)。
HoldOffHunger 2018年

+1。"onChange()"はReactJSの起動可能なイベントではなく、これが唯一の解決策です。出典:github.com/facebook/react/issues/1471
HoldOffHunger

42

この例からわかるように、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);
});

ラジオボタンオプションを選択するclickと、とchangeイベントの両方が発生します(少なくとも一部のブラウザでは)。

私の例では、clickイベントタブとキーボードを使用してオプションを選択したときにが発生おきます。

したがって、私のポイントは、changeイベントが発生するブラウザがいくつかある場合でも、イベントはclick必要なカバレッジを提供する必要があるということです。


6
はい、console.logIE7がサポートしていないステートメントがコードに含まれているためです。必要に応じて、IEで警告することもできます。
フィリップウォルトン

ありがとう。ただし、これは以前に選択されたチェックボックスを取得する方法には対応していません。また、おかげで、console.logがIEで機能しないことを知りませんでした。
Matthew

イベントハンドラーを2倍にしないでください。clickchangeイベントハンドラーの両方を起動するブラウザーでは、ハンドラーを2回呼び出すことになります。この場合、@ Matthewは以前の値に関係しているため、悪い結果につながる可能性があります。
ネイト・クック

3
@NateCookあなたは明らかに私の例の要点を逃した。changeイベントが発生するたびに、clickイベントも発生することを示しました。私の例で両方のイベントを使用していたからといって、それを宣伝していたわけではありません。私はあなたの反対票は相応しくないと思います。
フィリップウォルトン、

しかし、あなたはそれを宣伝していました-あなたの元の答えは「それで、私のポイントは、変更イベントが発生したとしてもブラウザによってはクリックイベントがフォールバックとして必要なカバレッジを提供し、ブラウザで変更を使用できるということですそれをサポートしています。」clickここで正しいハンドラであり、必要なのはこのハンドラだけです。あなたの改訂でそれが明らかになったので、私は私の反対票を削除します。
ネイト・クック

10

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はコールバック関数を介して渡されるイベントオブジェクトです。
エリック

6

ここでわかるように、http//www.w3schools.com/jsref/event_onchange.asp onchange属性は、ラジオボタンではサポートされていません。

あなたによってリンクされた最初のSOの質問はあなたに答えを与えます:onclick代わりにイベントを使用し、それがトリガーする関数内のラジオボタンの状態を確認してください。


これは少し不完全です。では、グループ内のすべてのクリックを処理する関数を作成した後、どのクリックが選択解除されているかを確認するにはどうすればよいでしょうか。また、jquery以外のソリューションを探しています。
Matthew

クリックされたラジオボタンがチェックされ、同じグループの他のすべてのチェックが外されます。または、そのグループのすべてのラジオボタンをループして、そのステータスを確認することもできます。ラジオボタンで何をしたいかについての詳細情報を提供した場合、次に進む方法を説明する方が簡単でしょう。
コンスタンティングロス

2
onclickキーボードフォームの選択が有効になっている場合、キーボード入力を介してラジオボタンのチェック状態を変更できるため、同じ意味ではありません。
gsnedders 2012年

@gsnedders onclickは、ほとんどのブラウザー(Firefox、IE、Safari、Chrome)でキーボード入力を介して機能するようです。それがonchangeがすることになっていることをするのは奇妙ですが、それはします。しかし、これがモバイルプラットフォームでどのように機能するか知りたいです。
Matthew

1
w3schoolsは1であり、以前に選択したラジオを取得する方法である2の問題全体に対処しませんでした。2は私の問題の中で最も重要な部分でした。
マシュー

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" />

それについてもう少し考えた後、変数を削除してクラスを追加/削除することにしました。ここに私が得たものがあります:http : //jsfiddle.net/BeQh3/2/


1
私はjQueryの使用を考えましたが、jQueryで実行できることは間違いなくたくさんあります。チェック済みと未チェックのいくつかのカスタムイベントをバインドし、クロスブラウザーの癖をチェックすることもできます。プラグインとしては良い考えのようです。
マシュー

ありがとう。私はjQueryが好きですが、この場合は利用できません。
マシュー

jQueryはどのように利用できませんか?
jmort253 2012年

1
jQueryが利用できない場合は、別の仕事を見つけます。
エイドリアン・カー

5

はい、現在選択されているラジオボタンの変更イベントはありません。しかし問題は、各ラジオボタンが個別の要素として扱われる場合です。代わりに、ラジオグループはのような単一の要素と見なされselectます。そのため、そのグループに対して変更イベントがトリガーされます。それがselect要素である場合、その中の各オプションについて心配するませんが、選択されたオプションのみを取ります。新しいオプションが選択されると、現在の値が変数に格納され、前の値になります。同様に、チェックされたラジオボタンの値を格納するために別の変数を使用する必要があります。

前のラジオボタンを識別するには、mousedownイベントでループする必要があります。

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

これを見てください:http : //jsfiddle.net/diode/tywx6/2/


マウスダウンを使用してクリックが発生する前に確認することを考えましたが、ラジオを選択するためにスペースを使用する場合は機能しません。多分あなたが言及したものの代わりに、またはそれに加えてフォーカスイベント。
Matthew

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

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

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

ありがとう。私はさらに少しいじくり回して、ラジオ自体を保管するかもしれません。このようにして、値が変化すると、値だけではなく、以前に選択したラジオへの参照ができます。
Matthew

@Matthew実際、私が共有したフィドルはラジオ要素を格納することであり、値だけではありませんでした。コードの目的を示すために値がログに記録されましたが、後で使用するために保存されませんでした。より明確になるように変数名を編集しています:previousChecked-> previousCheckedRadio、that-> currentCheckedRadio;
Dimitar Bonev 2012年

ありがとう。これは、ブラウザー間で適切に動作しない変更イベントを使用することを除いて、優れたソリューションです。代わりにクリックを使用した場合、それはより良いでしょう。
マシュー

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>

1
追加するonkeydown="radioChange('juju','button1',radioArray);"と、ユーザーがスペースを使用してラジオをチェックしたときにキャプチャすることもできます。
マシュー

2

これは頭​​の真上にありますが、ラジオボタンごとにonClickイベントを実行し、それらにすべての異なるIDを与え、イベントのforループを作成して、グループ内の各ラジオボタンを通過し、どれが'checked'属性を調べてチェックされました。チェックされたもののIDは変数として保存されますが、新しいラジオボタンがチェックされたかどうかにかかわらずクリックイベントが発生するため、最初に一時変数を使用して、その変数の値が変更されたことを確認することをお勧めします。


2
<input type="radio" name="brd" onclick="javascript:brd();" value="IN">   
<input type="radio" name="brd" onclick="javascript:brd();" value="EX">` 
<script type="text/javascript">
  function brd() {alert($('[name="brd"]:checked').val());}
</script>

2

インラインスクリプトを避けたい場合は、ラジオでクリックイベントをリッスンするだけです。これは、クリックイベントをリッスンすることにより、プレーンJavascriptで実現できます。

for (var radioCounter = 0 ; radioCounter < document.getElementsByName('myRadios').length; radioCounter++) {
      document.getElementsByName('myRadios')[radioCounter].onclick = function() {
        //VALUE OF THE CLICKED RADIO ELEMENT
        console.log('this : ',this.value);
      }
}

2

次のJSスクリプトを追加できます

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

1

これは私のために働く

<input ID="TIPO_INST-0" Name="TIPO_INST" Type="Radio" value="UNAM" onchange="convenio_unam();">UNAM

<script type="text/javascript">
            function convenio_unam(){
                if(this.document.getElementById('TIPO_INST-0').checked){
                    $("#convenio_unam").hide();
                }else{
                    $("#convenio_unam").show(); 
                }                               
            }
</script>

これがサポートされた今、これが答えになるはずだと思います。
レオ、

0

これは、checked = falseに必要な数のボタンを追加し、各ラジオボタンのonclickイベントでこの関数を呼び出すために使用する最も簡単で最も効率的な関数です。各ラジオボタンに一意の番号を指定します

function AdjustRadios(which) 
{
    if(which==1)
         document.getElementById("rdpPrivate").checked=false;
    else if(which==2)
         document.getElementById("rdbPublic").checked=false;
}

0

最も簡単で強力なフルウェイ

getAttributeを使用してラジオ入力のみを読み取る

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

if(e.target.getAttribute('name')=="myRadios")
console.log(e.target.value)
})
<input type="text"  value="iam text" /> 
<input type="radio" name="myRadios" value="1" /> 1
<input type="radio" name="myRadios" value="2" /> 2

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.