Обработчик события OnChange для переключателя (INPUT type = "radio") не работает как одно значение - PullRequest
157 голосов
/ 12 января 2012

Я ищу обобщенное решение для этого.

Рассмотрим 2 типа радиовходов с одинаковым именем.При отправке проверяемое значение определяет значение, отправляемое с помощью формы:

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

Событие изменения не срабатывает, если переключатель отключен.Таким образом, если радио со значением = "1" уже выбрано, а пользователь выбирает второе, handleChange1 () не запускается.Это создает проблему (для меня в любом случае) в том, что нет события, в котором я могу поймать этот отмена выбора.

Что мне нужно, так это обходной путь для события onchange для значения группы флажков или, в качестве альтернативы,Событие oncheck, которое обнаруживает не только когда радио проверено, но также и когда оно не проверено.

Я уверен, что некоторые из вас сталкивались с этой проблемой раньше.Какие есть обходные пути (или в идеале, как правильно это сделать)?Я просто хочу поймать событие изменения, получить доступ к ранее проверенному радио, а также к вновь установленному радио.

PS
onclick кажется лучшим (кросс-браузерным) событием, чтобы указать, когда радио проверяетсяно это все еще не решает не проверенную проблему.

Я полагаю, что имеет смысл, почему onchange для типа флажка работает в таком случае, так как оно изменяет значение, которое оно представляет, когда вы проверяете или отменяетеПроверь это.Я бы хотел, чтобы переключатели вели себя как замена элемента SELECT, но что вы можете сделать ...

Ответы [ 14 ]

149 голосов
/ 25 января 2012

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/

94 голосов
/ 27 января 2012

Я бы сделал два изменения:

<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;
}
32 голосов
/ 12 января 2012

Как видно из этого примера: 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 голосов
/ 02 февраля 2015

Как насчет использования события изменения 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/

6 голосов
/ 28 января 2012

Я не думаю, что есть какой-либо другой способ, кроме сохранения предыдущего состояния. Вот решение с 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/

5 голосов
/ 01 сентября 2012

Я понимаю, что это старая проблема, но этот фрагмент кода работает для меня. Возможно, кто-то в будущем найдет это полезным:

<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>
5 голосов
/ 24 января 2012

Сохранить предыдущее проверенное радио в переменной:
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);
4 голосов
/ 12 января 2012

Да, нет события изменения для выбранной в данный момент радиокнопки. Но проблема в том, что каждый переключатель выбран в качестве отдельного элемента. Вместо этого радиогруппа должна рассматриваться как отдельный элемент, такой как 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/

4 голосов
/ 12 января 2012

Как вы можете видеть здесь: http://www.w3schools.com/jsref/event_onchange.asp Атрибут onchange не поддерживается для переключателей.

Первый связанный с вами вопрос SO дает вам ответ: используйте вместо этого событие onclickи проверьте состояние переключателя внутри функции, которую она вызывает.

2 голосов
/ 07 мая 2015

Если вы хотите избежать встроенного скрипта, вы можете просто прослушать событие клика по радио. Этого можно достичь с помощью простого 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);
      }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...