Radyo düğmesi için onChange olay işleyicisi (INPUT type = “radio”) tek bir değer olarak çalışmıyor


190

Bunun için genelleştirilmiş bir çözüm arıyorum.

Aynı ada sahip 2 radyo tipi girişi düşünün. Gönderildiğinde, işaretlenen formla birlikte gönderilen değeri belirler:

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

Bir radyo düğmesinin seçimi kaldırıldığında change olayı başlatılmaz. Dolayısıyla, = "1" değerine sahip telsiz zaten seçiliyse ve kullanıcı ikinciyi seçerse, handleChange1 () çalışmaz. Bu da (benim için zaten) bir sorun yaratıyor, çünkü bu seçim seçimini yakalayabileceğim bir olay yok.

Ne istiyorum onay kutusu grup değeri için onchange olay veya alternatif olarak sadece bir radyo kontrol edildiğinde değil, aynı zamanda işaretli değil algılar bir oncheck olay için bir geçici çözümdür.

Eminim ki bazılarınız daha önce bu problemle karşılaştı. Bazı geçici çözümler nelerdir (ya da ideal olarak bununla başa çıkmanın doğru yolu nedir)? Sadece change olayını yakalamak, daha önce kontrol edilen radyoya ve yeni kontrol edilen radyoya erişmek istiyorum.

PS
onclick, bir radyonun ne zaman kontrol edildiğini belirtmek için daha iyi (çapraz tarayıcı) bir olay gibi görünüyor, ancak yine de kontrol edilmemiş sorunu çözmüyor.

Bir onay kutusu türü için onchange neden böyle bir durumda işe yaradığını, çünkü kontrol veya işaretini kaldırdığınızda gönderdiği değeri değiştirdiğini düşünüyorum. Radyo düğmelerinin bir SELECT elemanının değişmesi gibi davranmasını isterdim, ancak ne yapabilirsiniz?

Yanıtlar:


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>

İşte bir JSFiddle demosu: https://jsfiddle.net/crp6em1z/


4
Bunu neden doğru cevap olarak seçtiğime dair bir not: Seçili olan radyoyu tutan myRadiosdeğişkeni okumak için , ad düğmeli radyo düğmelerinin her birinde tıklama olay işleyicileri ayarlanır prev. Tıklanan radyonun saklanan radyo ile aynı olup olmadığına karar vermek için her tıklama işleyicisi içinde bir karşılaştırma yapılır prevve eğer değilse o anda tıklanan radyo orada saklanır. Tıklama işleyici içinde önceden seçilmiş prevolan radyoya ve şu anda seçili olan radyoya erişebilirsiniz :this
Matthew

26
İşlevin döngü dışında önbelleğe alınması daha iyi olur, böylece tüm radyolar aynı olay işleyiciyi paylaşır (şimdi aynı işleyicilere sahipler, ancak farklı işlevler). Veya tüm telsizleri bir paketleyiciye koyun ve etkinlik heyetini kullanın
Oriol

1
@Oriol veya bilgili herhangi biri, (1) döngü dışında önbellekleme veya (2) sarıcı + olay yetkisi verebilir misiniz?
Matt Voda


14
onclick klavye seçimi ile çalışmıyor, kullanabilirsiniz rad[i].addEventListener('change', function(){ //your handler code })ve hem fare hem de klavye için çalışacaktır
Juanmi Rodriguez

117

İki değişiklik yapardım:

<input type="radio" name="myRadios" onclick="handleClick(this);" value="1" />
<input type="radio" name="myRadios" onclick="handleClick(this);" value="2" />
  1. Kullanım onclickyerine işleyicisi onchange- Radyo girişinin "işaretli devlet" değiştiriyoruz değil value, bu yüzden bir değişiklik olay oluyor orada değil.
  2. Tek bir işlev kullanın ve thiso anda seçili değerin kontrol edilmesini kolaylaştıracak bir parametre olarak iletin.

ETA: handleClick()İşlevinizle birlikte , telsizin orijinal / eski değerini sayfa kapsamındaki bir değişkende izleyebilirsiniz. Yani:

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


Teşekkürler, ancak bu, önceki kontrol edilen radyoyu almak zorunda kalmama sorununu ele almıyor ve aynı zamanda diğer kullanıcıların daha önce bahsettiği, "onchange" yerine "onclick" kullanmak olan bir şeyi de belirtiyorsunuz. Aslında bunu en başından beri biliyordum ama değişimin beklendiği gibi çalışmadığına ve daha iyi işlemek istiyorum.
Matthew

1
JavaScript kullanıyorsunuz, değil mi? Öyleyse neden sadece bilinen son seçilen radyo düğmesini saklayan bir değişkeni korumakla kalmıyorsunuz? Tek bir işleyici kullanıyorsanız, yeni değerle üzerine yazmadan önce bu saklanan değeri kontrol edebilirsiniz. +1
jmort253

13
@Matthew: onclickİşleyici sadece kötü adlandırılmış - klavyedeki "enter" tuşuna basılarak düğmenin tıklanmış, dokunulmuş veya etkinleştirilmiş olup olmadığı radyo düğmesi seçimi olayını işler. onchangeGirişinde değer değişmez çünkü işleyicisi bu durumda uygun değildir, sadece kontrol / denetlenmeyen niteliğini. Önceki değeri ele almak için örnek bir komut dosyası ekledim.
Nate Cook

1
Kullanıcı radyoyu seçmek için klavyeyi (sekme + boşluk çubuğu) kullandıysa "onClick" olayı işlemez (ve bu büyük formlarda yaygın bir uygulamadır).
HoldOffHunger

+1. "onChange ()" ReactJS'de tetiklenebilir bir olay değildir ve bu tek çözümdür. Kaynak: github.com/facebook/react/issues/1471
HoldOffHunger

42

Bu örnekten de görebileceğiniz gibi: 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);
});

bir radyo düğmesi seçeneği seçildiğinde hem clickve changeolaylar tetiklenir (en azından bazı tarayıcılarda).

Ayrıca, clickörneğimde , bir seçenek belirlemek için sekmeyi ve klavyeyi kullandığınızda olayın hala tetiklendiğini belirtmeliyim.

Demek istediğim, changeolay tetiklendiğinde bazı tarayıcılar olsa da, etkinliğin clickihtiyacınız olan kapsamı sağlaması gerekir.


6
Evet, çünkü console.logkodumda IE7'nin desteklemediği bir ifade var. İsterseniz sadece IE'de uyarabilirsiniz.
Philip Walton

Teşekkürler. Bu, önceden seçilen onay kutusunun nasıl alınacağını ele almaz. Ayrıca teşekkürler, ben console.log IE çalışmadı bilmiyordum.
Matthew

Olay işleyicilerini ikiye katlamayın - hem clickve hem de changeolay işleyicileri tetikleyen tarayıcılarda , işleyiciyi iki kez çağırırsınız. Bu durumda, @Matthew önceki değerle ilgilendiğinden, kötü sonuçlara yol açabilir.
Nate Cook

3
@NateCook, örneğimin amacını açıkça kaçırdınız. Değişiklik olayı her tetiklendiğinde, tıklama etkinliğinin de tetiklendiğini gösteriyordum. Örneğimde her iki olayı da kullanmak, onu tanıttığım anlamına gelmiyor. Bence aşağı oyunuz hak edilmedi.
Philip Walton

Ama siz onu tanıtıyordunuz - orijinal cevabınız "Demek istediğim, değişiklik olayı tetiklense de bazı tarayıcılar olsa da, tıklama etkinliğinin yedek olarak ihtiyacınız olan kapsamı sağlaması ve tarayıcılarda değişikliği kullanabilmeniz destekliyor. " clickburada doğru işleyici ve ihtiyacınız olan tek şey. Revizyonunuz bunu açıklığa kavuşturuyor, bu yüzden aşağı oyumu kaldırıyorum.
Nate Cook

10

Jquery'nin değişiklik olayını kullanmaya ne dersiniz?

$(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()aynı zamanda yerel javascript ile değiştirilebilir e.currentTarget.value, burada e, geri arama işlevinden geçen olay nesnesidir.
Eric

6

Burada görebileceğiniz gibi: http://www.w3schools.com/jsref/event_onchange.asp Değiştirme özelliği radyo düğmeleri için desteklenmez.

Tarafınızdan bağlanan ilk SO sorusu size cevap verir: onclickBunun yerine olayı kullanın ve tetiklediği işlevin içindeki radyo düğmesi durumunu kontrol edin.


Bu biraz eksik. Peki, gruptaki tüm tıklamaları işlemek için bir işlev oluşturduktan sonra, hangisinin seçili olmadığını nasıl kontrol edersiniz? Ayrıca, jquery olmayan bir çözüm arıyorum.
Matthew

Tıklanan radyo düğmesi kontrol edilir, aynı gruptaki diğer tüm işaretler kaldırılır. Ya da, o grubun tüm radyo düğmelerinde dolaşabilir ve durumlarını kontrol edebilirsiniz. Radyo düğmeleriyle ne yapmak istediğiniz hakkında daha fazla bilgi verdiyseniz, nasıl devam edeceğinizi söylemek daha kolay olacaktır.
Constantin Groß

2
onclickklavye form seçimi etkinleştirildiğinde, klavye girişiyle radyo düğmesinin kontrol edilebilirliğini değiştirebileceğinizden aynı anlamsal değildir.
gsnedders

@gsnedders onclick çoğu tarayıcıda klavye girişi ile çalışıyor gibi görünüyor - Firefox, IE, Safari, Chrome. Değişimin yapması gerekeni yapması tuhaf, ama yapıyor. Bunun mobil platformlarda nasıl çalıştığını merak ediyorum.
Matthew

1
w3schools 1 ve daha önce seçilen radyo nasıl elde edildi 2 için tüm sorunu ele vermedi. 2 aklımdaki sorunun en önemli parçasıydı.
Matthew

6

Önceki durumu depolamaktan başka bir yol olduğunu düşünmüyorum. İşte jQuery ile çözüm

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

Biraz daha düşündükten sonra, değişkenten kurtulmaya ve sınıf ekle / kaldırmaya karar verdim. İşte ne var: http://jsfiddle.net/BeQh3/2/


1
Bir jQuery kullanarak düşündüm ve kesinlikle onunla yapılabilir çok daha fazla. İşaretli ve işaretsiz için bazı özel etkinlikleri bağlayabilir ve hatta tarayıcılar arası tuhaflıkları kontrol edebilirsiniz. Bir eklenti için iyi bir fikir gibi geliyor.
Matthew

Teşekkürler. Ben jQuery seviyorum ama bu durumda benim için mevcut değil.
Matthew

JQuery sizin için nasıl kullanılamaz?
jmort253

1
JQuery benim için uygun olmasaydı, farklı bir iş bulurdum.
Adrian Carr

5

Evet, seçili olan radyo düğmesi için değişiklik etkinliği yoktur. Ancak sorun, her radyo düğmesinin ayrı bir öğe olarak alınmasıdır. Bunun yerine bir radyo grubu gibi tek bir unsur olarak düşünülmelidir select. Bu nedenle değişiklik grubu o grup için tetiklenir. Bir öğeyse, selectiçindeki her seçenek hakkında asla endişelenmeyiz, sadece seçilen seçeneği alırız. Mevcut değeri, yeni bir seçenek belirlendiğinde önceki değer olacak bir değişkende saklarız. Benzer şekilde, kontrol edilen radyo düğmesinin değerini saklamak için ayrı bir değişken kullanmanız gerekir.

Önceki radyo düğmesini tanımlamak istiyorsanız, mousedownetkinliğe geri dönmeniz gerekir .

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

bakınız: http://jsfiddle.net/diode/tywx6/2/


Tıklama gerçekleşmeden önce kontrol etmek için fareyi kullanmayı düşündüm, ancak radyoyu seçmek için alan kullanırken işe yaramaz. Belki de bahsettiğiniz şeyin yerine veya bunlara ek olarak odak olayı.
Matthew

5

Önceki kontrol edilen radyoyu bir değişkende saklayın:
saklayın 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 ÖRNEK KODU

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

Teşekkürler. Kemanı biraz daha ileriye götürebilirim ve telsizin kendisini saklayabilirim. Bu şekilde değer değiştiğinde, sadece değeri yerine önceden seçilmiş radyoya bir referansınız olur.
Matthew

@Matthew Aslında paylaştığım keman radyo değerini saklıyordu, sadece değeri değil. Değer, kodun amacını göstermek için günlüğe kaydedildi, ancak daha sonra kullanılmak üzere saklanmadı. Değişken isimlerini daha açık hale getirmek için düzenliyorum: previousChecked -> previousCheckedRadio, o -> currentCheckedRadio;
Dimitar Bonev

Teşekkürler. Bu, tarayıcılar arasında düzgün davranmayan change olayı kullanmak dışında iyi bir çözümdür. Bunun yerine tıklama kullandıysanız daha iyi olurdu.
Matthew

5

Bunun eski bir sorun olduğunun farkındayım, ancak bu kod snippet'i benim için çalışıyor. Belki de gelecekte biri yararlı bulacaktır:

<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
Eğer eklerseniz onkeydown="radioChange('juju','button1',radioArray);", bir kullanıcı kullandığı uzay radyo kontrol etmek zaman da yakalayabilecek.
Matthew

2

Bu sadece başımın üstündedir, ancak her radyo düğmesi için bir onClick olayı yapabilir, onlara farklı kimlikler verebilir ve ardından gruptaki her radyo düğmesinden geçmek ve hangisinin olduğunu bulmak için bir for döngüsü yapabilirsiniz. "işaretli" özelliğe bakarak kontrol edildi. İşaretli olanın kimliği bir değişken olarak saklanır, ancak tıklama değişkeninin yeni bir radyo düğmesi işaretli olsa da olmasa da tetikleneceğinden, bu değişkenin değerinin değiştiğinden emin olmak için önce geçici bir değişken kullanmak isteyebilirsiniz.


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

Satır içi komut dosyasından kaçınmak istiyorsanız, radyodaki bir tıklama etkinliğini dinleyebilirsiniz. Bu, üzerinde bir tıklama etkinliğini dinleyerek düz Javascript ile gerçekleştirilebilir

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

Aşağıdaki JS komut dosyasını ekleyebilirsiniz

<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

bu benim için çalışıyor

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

Bence bu destekleniyor şimdi cevap olmalı.
Leo

0

Bu, kullanımı en kolay ve en verimli işlevdir, sadece check = false seçeneğine istediğiniz kadar düğme ekleyin ve her radyo düğmesinin onclick olayını bu işlevi çağırın. Her radyo düğmesine benzersiz bir numara atayın

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

0

En kolay ve tam yol gücü

getAttribute kullanarak salt okunur radyo girişleri

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.