Подтвердить что ты не робот

Как обнаружить событие отмены выбора радиокнопки?

Есть ли простой способ подключить событие "отменить выбор" на радиокнопке? Кажется, что событие изменения срабатывает только при выборе кнопки.

HTML

<input type="radio" id="one" name="a" />
<input type="radio" id="two" name="a" />

JavaScript

$('#one').change(function() {
    if(this.checked) {
        // do something when selected
    } else { // THIS WILL NEVER HAPPEN
        // do something when deselected
    }
});​

jsFiddle

4b9b3361

Ответ 1

Почему бы вам просто не создать настраиваемое событие вроде, скажем, deselect, и позволить ему запускать на всех членов группы с кликом, кроме самого элемента, который был нажат? Его способ проще использовать API обработки событий, который предоставляет jQuery таким образом.

HTML

<!-- First group of radio buttons -->
<label for="btn_red">Red:</label><input id="btn_red" type="radio" name="radio_btn" />
<label for="btn_blue">Blue:</label><input id="btn_blue"  type="radio" name="radio_btn" />
<label for="btn_yellow">Yellow:</label><input id="btn_yellow" type="radio" name="radio_btn" />
<label for="btn_pink">Pink:</label><input id="btn_pink"  type="radio" name="radio_btn" />
<hr />
<!-- Second group of radio buttons -->
<label for="btn_red_group2">Red 2:</label><input id="btn_red_group2" type="radio" name="radio_btn_group2" />
<label for="btn_blue_group2">Blue 2:</label><input id="btn_blue_group2"  type="radio" name="radio_btn_group2" />
<label for="btn_yellow_group2">Yellow 2:</label><input id="btn_yellow_group2" type="radio" name="radio_btn_group2" />
<label for="btn_pink_group2">Pink 2:</label><input id="btn_pink_group2"  type="radio" name="radio_btn_group2" />

JQuery

// Attaching click event handlers to all radio buttons...
$('input[type="radio"]').bind('click', function(){
    // Processing only those that match the name attribute of the currently clicked button...
    $('input[name="' + $(this).attr('name') + '"]').not($(this)).trigger('deselect'); // Every member of the current radio group except the clicked one...
});

$('input[type="radio"]').bind('deselect', function(){
    console.log($(this));
})

События выделения будут инициироваться только среди членов одной и той же радиогруппы (элементы, которые имеют одинаковый атрибут name).

jsFiddle solution

РЕДАКТИРОВАТЬ:. Чтобы учесть все возможные места размещения прикрепленного тега метки (обертывание радиоэлемента или присоединение через селектор id), возможно, лучше использовать событие onchange для запуска обработчиков. Благодаря Faust для указания этого.

$('input[type="radio"]').on('change', function(){
    // ...
}

Ответ 2

Вы можете создать настраиваемое событие "отменить выбор" относительно безболезненно, но поскольку вы уже обнаружили, что стандартное событие изменения запускается только на вновь установленном переключателе, а не на ранее проверенном, который только что был снят.

Если вы хотите сказать что-то вроде:

$("#one").on("deselect", function() {
    alert("Radio button one was just deselected");
});

Затем запустите что-то вроде следующей функции из обработчика готового документа (или поместите код непосредственно в обработчик документа):

function setupDeselectEvent() {
    var selected = {};
    $('input[type="radio"]').on('click', function() {
        if (this.name in selected && this != selected[this.name])
            $(selected[this.name]).trigger("deselect");
        selected[this.name] = this;
    }).filter(':checked').each(function() {
        selected[this.name] = this;
    });
}

Рабочая демонстрация: http://jsfiddle.net/s7f9s/2

Это означает, что на всех радиостанциях на странице размещен обработчик кликов (это не останавливает добавление ваших собственных обработчиков событий кликов к тем же радиостанциям), которые будут проверять, было ли ранее выбранное радио в той же группе (то есть с тем же именем), и если это так, инициируйте событие "отменить выбор" на этом радио. Затем он сохраняет только что щелкнутый, как текущий. Событие "отменить выбор" не запускается, если вы нажмете уже проверенную радиостанцию ​​или если ранее не было отмечено. Бит .filter().each() в конце - это отметить, какие радиостанции уже выбраны. (Если вам нужно обслуживать более одной формы на той же странице, имеющей независимые радиогруппы с таким же именем, тогда обновите соответствующую функцию соответственно.)

Ответ 3

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

Недостатком является то, что код в ветке отмены выбора будет работать, даже если ранее не был выбран переключатель. Если все, что вы делаете, это просто показать, скрыть или отключить элементы пользовательского интерфейса, это не имеет большого значения.

Чтобы использовать ваш пример:

buttons = $('input[name="a"]');
buttons.change(function() {
    buttons.trigger('update:groupA');

}).bind('update:groupA', function(){
    if(this.checked) {
        //Do your checked things
    } else {
        //Do your unchecked things. Gets called whenever any other button is selected, so don't toggle or do heavy computation in here.
    }
});​

Ответ 4

Я думаю, что это может произойти, потому что событие focus запускается перед событием change, поэтому следующая радиостанция, на которую вы нажимаете, будет сфокусирована до того, как предыдущая проверенная радио вызывает событие изменения. Не цитируйте меня на этом, хотя...

Вы можете сделать это следующим образом:

var isChecked = function(id) { alert(id + ': ' + $('#' + id).is(':checked')) }
$('input[name="a"]').change(function(){ isChecked('one') })

Демо: http://jsfiddle.net/elclanrs/cD5ww/

Ответ 5

Я думаю, вам нужно добавить функцию изменения на входном уровне, а не на каждом переключателе.

Попробуйте следующее:

$("input[name='a']").change(function() {
  $("input[name='a']").each(function(){
    if(this.checked) {
        // do something when selected
    } else {
        // do something when deselected
    }
  });   
});​

Ответ 6

Вы можете инициировать событие "change" самостоятельно. Это немного сложно, чтобы избежать пульта дистанционного управления, бесконечно вызывающего событие "change" друг на друга, но это можно сделать следующим образом:

$('input[type="radio"]').each(function() {
    var name = $(this).attr('name');
    var that = this;
    $('input[name="'+name+'"][type="radio"]').not(that)
        .on('change', function(e, alreadyTriggered) {
            if(!alreadyTriggered || alreadyTriggered.indexOf(this) == -1) {
                if(!alreadyTriggered) {
                    alreadyTriggered = [that];
                }
                alreadyTriggered.push(this);
                $(that).trigger('change', [alreadyTriggered]);
            }
    });
});

Здесь демонстрация приведенного выше кода.

Ответ 7

Я нашел обходной путь для моего конкретного случая, который может помочь. Это срабатывает, когда событие "отменить выбор" можно применить ко всем переключателям, которые не выбраны.

Я хотел:

  • добавить класс в элемент, когда был выбран радиобулок, и
  • удалить этот класс, когда кнопка "не выбрана" .

Мне довелось найти этот вопрос, потому что у меня была та же проблема:

$('input:radio').on('change', function() {
    if( $(this).is(':checked') ) {
        $(this).addClass('my-class-for-selected-buttons')
    } else { // THIS WILL NEVER HAPPEN
        $(this).removeClass('my-class-for-selected-buttons')
    }
});​

Но в моем случае решение было намного проще, потому что я могу попытаться удалить класс из всех радиокнопки довольно просто с помощью jQuery, а затем добавить класс к выбранному:

$('input:radio').on('change', function() {
    $('input:radio').removeClass('my-class-for-selected-buttons') // Here!

    if( $(this).is(':checked') ) {
        $(this).addClass('my-class-for-selected-buttons')
    }
});​

С помощью этой простой настройки мне не нужно было искать способ запуска события "отменить выбор".

Итак, если в вашем случае вы можете применить событие ко всем переключателям, которые не выбраны, а не только к тому, который был "отменен", вы можете использовать эту меру

Ответ 8

показывает это для ya?

http://jsfiddle.net/WZND9/6/

 $('input').change(function() {
    if ($('#one').is(':checked')) {
        alert('checked');
    } else { 
        alert('not checked');
    }
 });