Im Gegensatz zu Kontrollkästchen kann der Benutzer Optionsfelder nach dem Klicken nicht mehr deaktivieren. Gibt es eine Möglichkeit, sie mithilfe von Javascript programmgesteuert umzuschalten? Dies wäre vorzugsweise ohne Verwendung von jQuery.
Antworten:
Sie können HTML - Objekts Eigenschaft checked
auf false
wie folgt aus :
document.getElementById('desiredInput').checked = false;
PS: Halten Sie die CtrlTaste gedrückt, um das Kontrollkästchen zu deaktivieren.
if(e.ctrlKey) {...
if ctrlKey
und ... nun, Sie können es deaktivieren ... aber Sie können niemals ein Radio überprüfen, da die checked
Eigenschaft des [Klick] -Ereignisziels immer als aktiviert angezeigt wird .
Optionsfelder sollen in Gruppen verwendet werden, da sie dasselbe name
Attribut verwenden. Wenn Sie dann auf eine davon klicken, wird die Auswahl der aktuell ausgewählten Option aufgehoben. Damit der Benutzer eine von ihm getroffene „echte“ Auswahl abbrechen kann, können Sie ein Optionsfeld einfügen, das einer Nullauswahl entspricht, z. B. „Weiß nicht“ oder „Keine Antwort“.
Wenn Sie eine einzelne Schaltfläche wünschen, die aktiviert oder deaktiviert werden kann, verwenden Sie ein Kontrollkästchen.
Es ist möglich (aber normalerweise nicht relevant), ein Optionsfeld in JavaScript zu deaktivieren, indem Sie einfach seine checked
Eigenschaft auf false setzen, z
<input type=radio name=foo id=foo value=var>
<input type=button value="Uncheck" onclick=
"document.getElementById('foo').checked = false">
Dies ist meine Antwort (obwohl ich es mit jQuery gemacht habe, aber nur für Selektoren und Hinzufügen und Entfernen einer Klasse, so dass Sie es einfach durch reine JS-Selektoren und reine JS-Add-Attribute ersetzen können)
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
$(document).on("click", "input[name='radioBtn']", function(){
thisRadio = $(this);
if (thisRadio.hasClass("imChecked")) {
thisRadio.removeClass("imChecked");
thisRadio.prop('checked', false);
} else {
thisRadio.prop('checked', true);
thisRadio.addClass("imChecked");
};
})
click
s funktioniert einfach nicht, weil .checked
es immer wahr ist. mousedown
funktioniert nicht, weil es mouseup
ruiniert - auch mit e.preventDefault();e.stop[Immediate]Propagation();
; Die nächstbeste Technik ist der e.ctrlKey
oben erwähnte Ansatz - dies erfordert jedoch einige spezielle Kenntnisse des Benutzers. Der einzige Weg ist [wahrscheinlich] die Verwendung einer Art Sentinel wie a class
oderdata-checked
. Beweise mir bitte das Gegenteil !!!
Eingewickelt in ein Plugin
Einschränkungen:
(function($) {
$.fn.uncheckableRadio = function() {
var $root = this;
$root.each(function() {
var $radio = $(this);
if ($radio.prop('checked')) {
$radio.data('checked', true);
} else {
$radio.data('checked', false);
}
$radio.click(function() {
var $this = $(this);
if ($this.data('checked')) {
$this.prop('checked', false);
$this.data('checked', false);
$this.trigger('change');
} else {
$this.data('checked', true);
$this.closest('form').find('[name="' + $this.prop('name') + '"]').not($this).data('checked', false);
}
});
});
return $root;
};
}(jQuery));
$('[type=radio]').uncheckableRadio();
$('button').click(function() {
$('[value=V2]').prop('checked', true).trigger('change').trigger('click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<label><input name="myRadio" type="radio" value="V1" /> R1</label>
<label><input name="myRadio" type="radio" value="V2" /> R2</label>
<label><input name="myRadio" type="radio" value="V3" /> R3</label>
<button type="button">Change R2</button>
</form>
Da das Optionsfeld hauptsächlich in Gruppen verwendet wird, ist es viel einfacher, sie getElementsByName( ' ' );
in Ihrem Skript-Tag zu finden. Dadurch wird ein Array zurückgegeben, jedem untergeordneten Array ein Ereignis-Listener zugewiesen und der Prüfstatus festgelegt. Schauen Sie sich dieses Beispiel an.
var myRadios = document.getElementsByName('subscribe');
var setCheck;
var x = 0;
for(x = 0; x < myRadios.length; x++){
myRadios[x].onclick = function(){
if(setCheck != this){
setCheck = this;
}else{
this.checked = false;
setCheck = null;
}
};
}
In diesem Handbuch wird erläutert, wie der Code mit einer visuellen Demonstration funktioniert.
setCheck
Variable bedeutet hier nichts.
Während es in Bezug auf Javascript gefragt wurde, ist die Anpassung von jquery trivial ... mit dieser Methode können Sie nach dem Wert "null" suchen und ihn übergeben ...
var checked_val = "null";
$(".no_option").on("click", function(){
if($(this).val() == checked_val){
$('input[name=group][value=null]').prop("checked",true);
checked_val = "null";
}else{
checked_val = $(this).val();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="radio" name="group" class="no_option" value="0">option 0<br>
<input type="radio" name="group" class="no_option" value="1">option 1<br>
<input type="radio" name="group" class="no_option" value="2">option 2<br>
<input type="radio" name="group" class="no_option" value="3">option 3<br>
<input type="radio" name="group" class="no_option" value="4">option 4<br>
<input type="radio" name="group" class="no_option" value="5">option 5<br>
<input type="radio" name="group" class="no_option" value="6">option 6<br>
<input type="radio" name="group" class="no_option" value="null" style="display:none">
Alte Frage, aber die Leute kommen immer wieder von Google hierher und OP wird vorzugsweise ohne jQuery gestellt. Hier ist meine Aufnahme.
Sollte auch auf IE 9 funktionieren
// iterate using Array method for compatibility
Array.prototype.forEach.call(document.querySelectorAll('[type=radio]'), function(radio) {
radio.addEventListener('click', function(){
var self = this;
// get all elements with same name but itself and mark them unchecked
Array.prototype.filter.call(document.getElementsByName(this.name), function(filterEl) {
return self !== filterEl;
}).forEach(function(otherEl) {
delete otherEl.dataset.check
})
// set state based on previous one
if (this.dataset.hasOwnProperty('check')) {
this.checked = false
delete this.dataset.check
} else {
this.dataset.check = ''
}
}, false)
})
<label><input type="radio" name="foo" value="1"/>foo = 1</label><br/>
<label><input type="radio" name="foo" value="2"/>foo = 2</label><br/>
<label><input type="radio" name="foo" value="3"/>foo = 3</label><br/>
<br/>
<label><input type="radio" name="bar" value="1"/>bar = 1</label><br/>
<label><input type="radio" name="bar" value="2"/>bar = 2</label><br/>
<label><input type="radio" name="bar" value="3"/>bar = 3</label><br/>
Sie können Uncheck nicht einfach über if(this.checked) this.checked = false
(wenn Sie wirklich wollen, sehen Sie sich den Hacker-Weg am Ende an) implementieren , da die Ereignisse in dieser Reihenfolge ausgelöst werden:
mousedown
oder keydown
mouseup
oder keyup
click
input
(nur wenn der Status geändert wird)change
(nur wenn der Status geändert wird)In welchem Fall soll nun das erwähnte Uncheck durchgeführt werden?
mouseup
oder mousedown
: dann wird in Schritt 3 der Wert auf true zurückgesetzt und das Änderungs- und Eingabeereignis wird nicht einmal ausgelöst, da sich der Status nicht geändert hat, als sie in der Sequenz aufgerufen wurden - Sie können ihn also hier nicht deaktivierenclick
: dann ist der Status immer falsch und Eingabe und Änderung werden auch nicht ausgelöst - Sie können ihn also nicht überprüfeninput
oder change
: Es wird nicht ausgelöst, wenn der Status nicht geändert wird und wenn Sie auf das ausgewählte Element klicken, wird der Status nicht geändert. Sie können hier also nichts Nützliches tunWie Sie aus der obigen Sequenz lernen können, ist der Weg:
mouseup
click
als Negation des vorherigen StatusWenn Sie den vorherigen Status im Datenattribut speichern möchten, beachten Sie, dass er als Zeichenfolge gespeichert wird , während das aktivierte Attribut boolesch ist . Sie können es also wie folgt implementieren:
radio.onmouseup = function() { this.dataset.checked = this.checked? 1 : ""; }
radio.onclick = function() { this.checked = !this.dataset.checked; }
Es scheint zu funktionieren, aber Sie sollten dies aus folgenden Gründen nicht tun:
mousedown
anderen Stelle über dem mouseup
Optionsfeld schweben und dann : In diesem Fall wird Mouseup ausgelöst und Klick nichtEs gibt noch ein anderes Problem: Dynamisch hinzugefügte Optionsfelder. Es gibt zwei Möglichkeiten:
element.appendChild(radio)
- Wenn Sie die Auswahl für alle Funkgeräte im DOMContentLoaded
Ereignis aktivieren , ist dieses dynamisch hinzugefügte Funkgerät nicht betroffenelement.innerHTML+= '<input type="radio">'
- Ersetzt effektiv den HTML-Inhalt des Elements und erstellt das darin enthaltene DOM neu. - Alle Ereignis-Listener werden verworfenUm (2) zu lösen, empfehle ich das Inhaltsattribut onclick . Beachten Sie das element.onclick = fn
und element.setAttribute("onclick", "fn()")
sind zwei verschiedene Dinge. Beachten Sie auch, dass onclick
jedes Mal ausgelöst wird , wenn der Benutzer das Radio aktiviert, unabhängig von der von ihm verwendeten Schnittstelle.
Noch ein Problem: Wenn Sie die Auswahl deaktivieren, sollten Sie auch das Umschalten aktivieren Space, um das Verhalten von Kontrollkästchen nachzuahmen. Der folgende Code löst alle genannten Probleme:
function deselectableRadios(rootElement) {
if(!rootElement) rootElement = document;
if(!window.radioChecked) window.radioChecked = null;
window.radioClick = function(e) {
const obj = e.target;
if(e.keyCode) return obj.checked = e.keyCode!=32;
obj.checked = window.radioChecked != obj;
window.radioChecked = obj.checked ? obj : null;
}
rootElement.querySelectorAll("input[type='radio']").forEach( radio => {
radio.setAttribute("onclick", "radioClick(event)");
radio.setAttribute("onkeyup", "radioClick(event)");
});
}
deselectableRadios();
<label><input type="radio" name="tag1">one</label>
<label><input type="radio" name="tag1">two</label>
<label><input type="radio" name="tag1">three</label>
<label><input type="radio" name="tag1">four</label>
Jetzt können Sie jederzeit anrufen, deselectableRadios()
wenn Sie Inhalte dynamisch hinzufügen, und wenn Sie sie mehrmals über Funkgeräte aufrufen, wird dies nicht beschädigt. Sie können auch die angebenrootElement
, dass nur ein Teilbaum von HTML DOM aktualisiert und Ihr Web schneller gemacht werden soll. Wenn Ihnen der globale Status nicht gefällt, können Sie den Hacker-Weg verwenden:
Der Punkt ist , um Missbrauch setTimeout
auf mouseup
sich , nachdem die Eigenschaft checked rufen wird:
function deselectable() {
setTimeout(checked => this.checked = !checked, 0, this.checked);
}
Jetzt können Sie jedes Optionsfeld deaktivieren:
radio.onmouseup = deselectable;
Dieser einfache Einzeiler funktioniert jedoch nur mit einem Klick und löst die oben genannten Probleme nicht.
Deaktivierbares Radio ist im Grunde ein Kontrollkästchen, bei dem nur eines in der Gruppe aktiviert werden kann. Wenn Ihr Browser die CSS4-Funktion für das Erscheinungsbild unterstützt, können Sie dies einfach tun
<input type="checkbox" name="foo" style="appearance: radio">
und dann im onclick
Ereignis getElementsByName("foo")
und deaktivieren Sie alle verbleibenden Kontrollkästchen des Namens (Kontrollkästchen senden keinen Wert, wenn sie nicht aktiviert sind).
Ich bin hierher gekommen, weil ich das gleiche Problem hatte. Ich wollte dem Benutzer die Optionen präsentieren, während ich die Option ließ, leer zu bleiben. Dies ist zwar möglich, um explizit mithilfe von Kontrollkästchen zu codieren, die das Back-End erschweren würden.
Wenn der Benutzer Strg + Klicken hat, ist dies fast so gut, als wenn er es über die Konsole deaktiviert. Das Fangen der Maus ist zu früh und ein Klick ist zu spät.
Nun, endlich ist hier eine Lösung! Fügen Sie diese wenigen Zeilen einfach einmal auf die Seite ein und Sie haben sie für alle Optionsfelder auf der Seite erstellt. Sie können sogar mit dem Selektor herumspielen, um ihn anzupassen.
window.onload = function() {
document.querySelectorAll("INPUT[type='radio']").forEach(function(rd) {
rd.addEventListener("mousedown", function() {
if(this.checked) {
this.onclick=function() {
this.checked=false
}
} else {
this.onclick=null
}
})
})
}
<input type=radio name=unchecksample> Number One<br>
<input type=radio name=unchecksample> Number Two<br>
<input type=radio name=unchecksample> Number Three<br>
<input type=radio name=unchecksample> Number Four<br>
<input type=radio name=unchecksample> Number Five<br>
Dafür bin ich gekommen:
function uncheck_radio_before_click(radio) {
if(radio.prop('checked'))
radio.one('click', function(){ radio.prop('checked', false); } );
}
$('body').on('mouseup', 'input[type="radio"]', function(){
var radio=$(this);
uncheck_radio_before_click(radio);
})
$('body').on('mouseup', 'label', function(){
var label=$(this);
var radio;
if(label.attr('for'))
radio=$('#'+label.attr('for')).filter('input[type="radio"]');
else
radio=label.children('input[type="radio"]');
if(radio.length)
uncheck_radio_before_click(radio);
})
Erweitern der Antwort von user3716078, um mehrere unabhängige Optionsfeldgruppen und eine übersichtlichere Methode zum Zuweisen von Ereignis-Listenern zu mehreren Elementen zu ermöglichen ...
window.onload = function() {
var acc_checked=[];
[].slice.call(document.querySelectorAll('.accordion input[type="radio"]')).forEach(function(el,i){
/**
* i represents the integer value of where we are in the loop
* el represents the element in question in the current loop
*/
el.addEventListener('click', function(e){
if(acc_checked[this.name] != this) {
acc_checked[this.name] = this;
} else {
this.checked = false;
acc_checked[this.name] = null;
}
}, false);
});
}
Vollständiges Beispiel in reinem JavaScript:
box.onmouseup = function() {
var temp = this.children[0];
if (temp.checked) {
setTimeout(function() {
temp.checked = false;
}, 0);
}
}
<label id='box' style='margin-right: 1em;'>
<input type='radio' name='chk_préf_méd_perso' value='valeur'>
libellé
</label>
Ich werde versuchen, eine kleine Antwort mit 3 Optionsfeldern zu geben, Sie können später etwas hinzufügen.
const radios = Array.from(document.getElementsByClassName('radio'))
for(let i of radios) {
i.state = false
i.onclick = () => {
i.checked = i.state = !i.state
for(let j of radios)
if(j !== i) j.checked = j.state = false
}
}
<input class="radio" type="radio">X
<input class="radio" type="radio">Y
<input class="radio" type="radio">Z
Jetzt wollte ich dies in meinem Rails-Projekt implementieren, das mehrere Formulare enthält (abhängig, aus der Datenbank abgerufen). Jedes Formular verfügt über 2 sichtbare Optionsfelder + 1 verstecktes Optionsfeld.
Ich möchte, dass der Benutzer das Optionsfeld jedes Formulars auswählt / abwählt. Wenn Sie eine in einem Formular auswählen, sollte die Auswahl der anderen ausgewählten Schaltfläche in einem anderen Formular nicht aufgehoben werden. Also habe ich lieber folgendes gemacht:
var radios = Array.from(document.getElementsByClassName('radio'))
for (let i of radios) {
i.state = false
i.onclick = () => {
i.checked = i.state = !i.state
for (let j of radios)
if (j !== i) j.state = false
}
}
<form>
<input class="radio" name="A" type="radio">A
<input class="radio" name="A" type="radio">B
<input class="radio" name="A" type="radio">C
</form>
<form>
<input class="radio" name="A" type="radio">D
<input class="radio" name="A" type="radio">E
<input class="radio" name="A" type="radio">F
</form>
<form>
<input class="radio" name="SOMETHING" type="radio">G
<input class="radio" name="SOMETHING" type="radio">H
<input class="radio" name="SOMETHING" type="radio">I
</form>
Sie sehen, dass alle den gleichen Namen haben, aber sie haben unterschiedliche Formen, gruppiert nach 3, sodass dies für mehrere Formen funktioniert.
Die meisten modernen Browser betrachten checked="anything"
als checked="true"
.
Möglicherweise müssen Sie das aktivierte Attribut entfernen, wenn dies in Ihrem Fall sinnvoll ist. Eines davon hängt möglicherweise mit dem Laden der Seite zusammen.
$(this).removeAttr('checked')
Dies kann Ihnen in Fällen helfen, in denen Sie möchten, dass Ihr Optionsfeld unter bestimmten Bedingungen überprüft wird. Sie können das Attribut einfach entfernen, um dies zu erreichen.
PS: Nicht in allen Fällen hilfreich.
Sie könnten die verwenden checked
Eigenschaft eines Optionsfelds verwenden, um es zu deaktivieren.
Etwas wie das:
<script>
function uncheck()
{
document.getElementById('myRadio').checked = false;
}
function check()
{
document.getElementById('myRadio').checked = true;
}
</script>
<input id="myRadio" type="radio" checked="checked"/>
<button onclick="uncheck();">Uncheck</button>
<button onclick="check();">Check</button>
Sehen Sie es hier in Aktion: http://jsfiddle.net/wgYNa/
Der vollständige Code sieht ungefähr so aus
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<input name="radio" type="radio" id="myRadio" value="myRadio" checked="checked" onclick="setRadio(this)" />
<label for="myRadio"></label>
<script language="javascript">
function setRadio(obj)
{
obj.checked = false;
}
</script>
</body>
</html>
Hier ist ein Beispiel dafür, wo es wohl angebracht ist, andere Optionsfelder zu deaktivieren, als eine neue Auswahl zu treffen. Ich habe ein Wörterbuch, dessen Einträge mit einer Vielzahl von Indizes ausgewählt werden können. Welcher Index verwendet werden soll, wird über eine Reihe von Optionsfeldern ausgewählt. Es gibt jedoch auch eine Schaltfläche "Zufällige Eingabe", die der Benutzer verwenden kann, wenn er nur surfen möchte. Es wäre irreführend, einen Index an Ort und Stelle zu lassen, wenn der Eintrag über die Schaltfläche für zufällige Eingaben ausgewählt wurde. Wenn diese Schaltfläche gedrückt wird, deaktiviere ich alle Optionsfelder für die Indexauswahl und ersetze den Inhalt des Indexrahmens durch eine leere Seite .
required="required"
. Andernfalls müssen Sie entweder einen Wert an den Server senden und davon ausgehen, dass jeder Benutzer gut und gründlich über die Interaktion mit dieser Funkgruppe und die möglichen Auswirkungen auf die Funktionsweise des Servers nachgedacht hat - oder ein Optionsfeld für die von mir ausgewählte Option bereitstellen eine Option, und dann wurde mir klar, dass es mir egal ist, aber da Radios nicht deaktiviert werden können, ist dies die einzige Option, die mir bleibt . Oder ein Web 1.0-Reset.
Wenn Sie Iclick-Pluging verwenden, ist dies so einfach wie unten dargestellt.
$('#radio1').iCheck('uncheck');
Leider funktioniert es nicht in Chrome oder Edge, aber in FireFox:
$(document)
// uncheck it when clicked
.on("click","input[type='radio']", function(){ $(this).prop("checked",false); })
// re-check it if value is changed to this input
.on("change","input[type='radio']", function(){ $(this).prop("checked",true); });
Ein funktionierendes fehlerfreies Update zur Antwort von Shmili Breuer.
(function() {
$( "input[type='radio'].revertible" ).click(function() {
var $this = $( this );
// update and remove the previous checked class
var $prevChecked = $('input[name=' + $this.attr('name') + ']:not(:checked).checked');
$prevChecked.removeClass('checked');
if( $this.hasClass("checked") ) {
$this.removeClass("checked");
$this.prop("checked", false);
}
else {
$this.addClass("checked");
}
});
})();
Das hat bei mir fast geklappt.
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
$(document).on("click", "input[name='radioBtn']", function(){
thisRadio = $(this);
if (thisRadio.hasClass("imChecked")) {
thisRadio.removeClass("imChecked");
thisRadio.prop('checked', false);
} else {
thisRadio.prop('checked', true);
thisRadio.addClass("imChecked");
};
})
Aber wenn ich ein Optionsfeld überprüfe, dann überprüfe ich ein anderes und versuche erneut, das erste zu aktivieren. Ich muss zwei Klicks machen. Dies liegt daran, dass die Klasse imChecked ist. Ich musste nur die anderen Optionsfelder vor der Überprüfung deaktivieren.
Wenn Sie diese Zeile hinzufügen, funktioniert es:
$ ("input [name = 'radioBtn']"). not (thisRadio) .removeClass ("imChecked");
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
$(document).on("click", "input[name='radioBtn']", function(){
thisRadio = $(this);
$("input[name='radioBtn']").not(thisRadio).removeClass("imChecked");
if (thisRadio.hasClass("imChecked")) {
thisRadio.removeClass("imChecked");
thisRadio.prop('checked', false);
} else {
thisRadio.prop('checked', true);
thisRadio.addClass("imChecked");
};
})
Der folgende Code reicht aus.
$('input[type=radio]').click(function() {
if($(this).hasClass("checked")){
this.checked = false;
$(this).removeClass("checked")
}else{
$(this).addClass("checked")
}
});
Angenommen, Sie haben eine Schaltfläche, auf die Sie beim Klicken alle Optionsfelder auf "Falsch" setzen können. Sie können den folgenden Code in den Onclick-Handler schreiben.
Unter dem Code befinden sich Optionsfelder, die auf dem Klassennamen basieren, und für jedes Element wird es als falsch markiert.
var elements=document.getElementsByClassName('Button');
Array.prototype.forEach.call(elements, function(element) {
element.checked = false;
});
$0.checked=false