단일 선택 단추 (INPUT type =“radio”)에 대한 OnChange 이벤트 핸들러가 하나의 값으로 작동하지 않습니다


190

이에 대한 일반화 된 솔루션을 찾고 있습니다.

같은 이름을 가진 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 요소의 온 체인지처럼 동작하기를 원하지만 할 수있는 일은 ...

답변:


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변수를 읽기 위해 name 속성 을 가진 각 라디오 버튼에 클릭 이벤트 핸들러가 설정됩니다 prev. prev클릭 된 라디오가 저장된 라디오와 동일한 지 그리고 그렇지 않은 경우 현재 클릭 된 라디오가 저장된 것인지 결정하기 위해 각 클릭 핸들러 내에서 비교가 수행됩니다 . 클릭 핸들러 내에서 이전에 선택한 : prev및 현재 선택된 라디오에 액세스 할 수 있습니다 .this
Matthew

26
모든 라디오가 동일한 이벤트 핸들러를 공유 할 수 있도록 루프 외부에서 함수를 캐시하는 것이 좋습니다. 이제 동일한 핸들러가 있지만 다른 함수입니다. 또는 모든 라디오를 포장지 안에 넣고 이벤트 위임을 사용하십시오
Oriol

1
@Oriol 또는 지식이 풍부한 사람이라면 (1) 루프 외부 캐싱 또는 (2) 래퍼 + 이벤트 위임의 예를들 수 있습니까?
Matt Voda


14
온 클릭 키보드 선택이 작동하지 않습니다, 당신은 사용할 수 있습니다 rad[i].addEventListener('change', function(){ //your handler code })그리고 그것은 모두 마우스 및 키보드 작동합니다
후안 미 로드리게스

117

나는 두 가지 변경을 할 것입니다 :

<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가 예상대로 작동하지 않으며 더 잘 처리하고 싶다는 사실에주의를 기울이고 싶었습니다.
Matthew

1
JavaScript를 사용하고 있습니까? 그렇다면 마지막으로 선택된 라디오 버튼을 저장하는 변수를 유지하는 것이 어떻습니까? 단일 핸들러를 사용하는 경우 새 값으로 겹쳐 쓰기 전에이 저장된 값을 확인할 수 있습니다. +1
jmort253

13
@Matthew : onclick핸들러의 이름이 잘못되었습니다. 키보드에서 "enter"를 눌러 버튼을 클릭, 터치 또는 활성화하는지 여부에 관계없이 라디오 버튼 선택 이벤트를 처리합니다. onchange입력의 값이 변경되지 않기 때문에 핸들러이 경우에는 적합하지 않다 만이 선택 / 선택 해제 특성. 이전 값을 처리하기 위해 예제 스크립트를 추가했습니다.
Nate Cook

1
사용자가 키보드 (탭 + 스페이스 바)를 사용하여 라디오를 선택한 경우 "onClick"은 이벤트를 처리하지 않습니다 (대형에서는 일반적입니다).
HoldOffHunger

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

라디오 버튼 옵션 (적어도 일부 브라우저에서는)을 선택 하면 clickchange이벤트가 모두 발생합니다.

또한 내 예제에서 탭과 키보드를 사용하여 옵션을 선택하면 click이벤트 가 계속 발생 한다는 것을 지적해야합니다 .

따라서 요점은 change이벤트가 시작 되더라도 일부 브라우저이지만 click이벤트는 필요한 범위를 제공해야한다는 것입니다.


6
예, console.log내 코드에는 IE7이 지원하지 않는 명령문 이 있기 때문입니다 . 원한다면 IE에서 경고 할 수 있습니다.
Philip Walton

감사. 그래도 이전에 선택한 확인란을 얻는 방법은 다루지 않습니다. 또한 감사합니다 .console.log가 IE에서 작동하지 않았다는 것을 몰랐습니다.
Matthew

이벤트 처리기를 두 배로 늘리지 마십시오. clickchange처리기를 모두 실행하는 브라우저 에서 처리기를 두 번 호출하게됩니다. 이 경우 @Matthew는 이전 값과 관련이 있기 때문에 나쁜 결과를 초래할 수 있습니다.
Nate Cook

3
@NateCook 내 예제의 요점을 분명히 놓쳤다. 변경 이벤트가 시작될 때마다 클릭 이벤트도 시작되는 것으로 나타났습니다. 예제에서 두 이벤트를 모두 사용했다고해서이를 홍보한다는 의미는 아닙니다. 당신의 투표가 과분하다고 생각합니다.
Philip Walton

그러나 당신은 그것을 홍보하고 있습니다-원래의 대답은 "그래서 요점은 변경 이벤트가 시작되었지만 일부 이벤트는 클릭 이벤트가 대체로 필요한 적용 범위를 제공해야하며 브라우저에서 변경 사항을 사용할 수 있다는 것입니다 "지원합니다." click여기에 올바른 처리기와 필요한 유일한 처리기가 있습니다. 귀하의 개정은 그것을 명확히하므로 다운 투표를 제거하고 있습니다.
네이트 쿡

10

Jquery의 변경 이벤트를 사용하는 것은 어떻습니까?

$(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는 콜백 함수를 통해 전달되는 이벤트 객체입니다.
Eric

6

여기에서 볼 수 있듯이 http://www.w3schools.com/jsref/event_onchange.asp 라디오 버튼에는 onchange 속성이 지원되지 않습니다.

당신에 의해 링크 된 첫 번째 SO 질문은 당신에게 대답을 제공합니다 : onclick대신 이벤트를 사용하고 그것이 트리거하는 함수 내부의 라디오 버튼 상태를 확인하십시오.


이것은 약간 불완전합니다. 따라서 그룹의 모든 클릭을 처리하는 기능을 만든 후 선택 해제 된 항목을 확인하려면 어떻게해야합니까? 또한 jquery가 아닌 솔루션을 찾고 있습니다.
Matthew

클릭 한 라디오 버튼이 선택되고 같은 그룹의 다른 모든 버튼은 선택 해제됩니다. 또는 해당 그룹의 모든 라디오 버튼을 반복하여 상태를 확인할 수 있습니다. 라디오 버튼으로 수행하려는 작업에 대한 자세한 정보를 제공 한 경우 진행 방법을보다 쉽게 ​​알 수 있습니다.
Constantin Groß

2
onclick키보드 양식 선택이 활성화되어있는 경우 키보드 입력을 통해 라디오 버튼의 검사를 변경할 수 있으므로 같은 의미론이 아닙니다.
gsnedders

@gsnedders onclick은 Firefox, IE, Safari, Chrome과 같은 대부분의 브라우저에서 키보드 입력을 통해 작동하는 것으로 보입니다. 온 체인지가해야 할 일을하는 것은 이상하지만, 그렇게한다. 그래도 이것이 모바일 플랫폼에서 어떻게 작동하는지 궁금합니다.
Matthew

1
w3schools는 1이고 이전에 선택한 라디오를 얻는 방법은 2의 전체 문제를 해결하지 못했습니다. 내 마음에 질문의 2가 가장 중요했습니다.
Matthew

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를 사용하는 것에 대해 생각했으며 분명히 할 수있는 일이 더 많이 있습니다. 체크 및 체크되지 않은 일부 사용자 지정 이벤트를 바인딩하고 크로스 브라우저 문제를 확인할 수도 있습니다. 플러그인에 대한 좋은 생각처럼 들립니다.
Matthew

감사. jQuery가 마음에 들지만이 경우에는 사용할 수 없습니다.
Matthew

jQuery를 어떻게 사용할 수 없습니까?
jmort253

1
jQuery를 사용할 수 없다면 다른 직업을 찾게 될 것입니다.
Adrian Carr

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

감사. 이것은 교차 브라우저가 올바르게 작동하지 않는 변경 이벤트를 사용하는 것 외에는 좋은 솔루션입니다. 대신 클릭을 사용하면 더 좋습니다.
Matthew

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);"하면 사용자가 공간을 사용하여 라디오를 확인할 때 캡처 할 수도 있습니다.
Matthew

2

이것은 내 머리 꼭대기에 있지만, 각 라디오 버튼에 대해 onClick 이벤트를 수행하고 모든 다른 ID를 제공 한 다음 이벤트에서 for 루프를 만들어 그룹의 각 라디오 버튼을 통과하고 어느 것이 'checked'속성을보고 확인했습니다. 체크 된 ID는 변수로 저장되지만, 새로운 라디오 버튼의 체크 여부에 따라 click 이벤트가 시작되므로 temp 변수를 먼저 사용하여 해당 변수의 값이 변경되었는지 확인할 수 있습니다.


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

인라인 스크립트를 피하려면 라디오에서 클릭 이벤트를 수신하면됩니다. 클릭 이벤트를 들으면서 일반 자바 스크립트로이를 달성 할 수 있습니다.

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>

나는 이것이 지금 지원되는 답변이라고 생각합니다.
Leo

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.