checked とは何か
checked は、checkbox と radio の「選択状態」を表す真偽値プロパティです。true なら選ばれている、false なら選ばれていない状態を意味します。ここが重要です:checked は“状態”で、送信時に渡す“文字列”は value。未チェックの checkbox は FormData にキー自体が入らないため、存在判定を使うのが正確です。
checkbox の読み取り・書き換え(状態と送信値の切り分け)
現在の選択状態を読む・変更する
<input id="agree" type="checkbox" value="yes">
<script>
console.log(agree.checked); // true/false
agree.checked = true; // 選択状態にする
agree.checked = false; // 選択解除
</script>
HTMLここが重要です:checked はブール値で直接読む・書く。見た目のトグルに対応します。
送信相当の値を理解する(FormData)
<form id="f">
<input name="agree" type="checkbox" value="yes">
</form>
<script>
const fd1 = new FormData(f); console.log(fd1.has("agree")); // false(未チェック)
f.elements.agree.checked = true;
const fd2 = new FormData(f); console.log(fd2.get("agree")); // "yes"
</script>
HTMLここが重要です:未チェックは“キーがない”。checked を見るか、FormData.has(“agree”) で有無判定をすると確実です。value は“送る文字列”であり、状態そのものではありません。
indeterminate(半チェック)で「一時表示だけ半透明」
<input id="all" type="checkbox">
<script>
all.indeterminate = true; // 半チェックの視覚状態(送信・ロジック上は未選択)
HTMLここが重要です:indeterminate は“見た目の中間状態”を出すだけ。checked ではないため、送信も選択処理もされません。マスター選択の視覚に便利です。
radio の読み取り・書き換え(グループで扱うのが正解)
選ばれている一つを読む
<form id="f">
<label><input type="radio" name="color" value="red">赤</label>
<label><input type="radio" name="color" value="blue">青</label>
</form>
<script>
const group = f.elements["color"]; // RadioNodeList
console.log(group.value); // 選択中の value(未選択なら空文字)
</script>
HTMLここが重要です:同じ name のラジオは“集合”として扱い、RadioNodeList.value で現在の選択値が取れます。
プログラムで選択する
<script>
// value 指定で選択
[...group].forEach(r => r.checked = (r.value === "blue"));
// あるいは個別参照してチェック
const red = [...group].find(r => r.value === "red");
red.checked = true;
</script>
HTMLここが重要です:ラジオは一つだけが選ばれるため、checked を true にした瞬間、他は自動で false になります。
イベントと UI 同期(input / change と明示発火)
ユーザー操作に反応して処理する
<input id="agree" type="checkbox">
<script>
agree.addEventListener("input", () => console.log("途中変化:", agree.checked));
agree.addEventListener("change", () => console.log("確定:", agree.checked));
</script>
HTMLここが重要です:input は“即時”、change は“確定後”に発火。ライブ反応なら input、検証や送信前の最終チェックは change が向いています。
プログラム変更でイベントを発火させる
<script>
agree.checked = true; // これだけでは change が発火しないことが多い
agree.dispatchEvent(new Event("change", { bubbles: true }));
</script>
HTMLここが重要です:コードで状態を変えた後にロジックを走らせたい場合、イベントを明示的に dispatch します。
実践例(すべて選択・一部選択と indeterminate・相互排他)
チェックボックスの「すべて選択」を正しく実装
<input id="all" type="checkbox"> 全て
<div>
<label><input class="item" type="checkbox" value="A">A</label>
<label><input class="item" type="checkbox" value="B">B</label>
<label><input class="item" type="checkbox" value="C">C</label>
</div>
<script>
const items = [...document.querySelectorAll(".item")];
function syncMaster() {
const checkedCount = items.filter(i => i.checked).length;
all.checked = checkedCount === items.length;
all.indeterminate = checkedCount > 0 && checkedCount < items.length;
}
all.addEventListener("change", () => {
items.forEach(i => i.checked = all.checked);
syncMaster();
});
items.forEach(i => i.addEventListener("change", syncMaster));
syncMaster();
</script>
HTMLここが重要です:マスター側は“全選択なら checked、部分選択なら indeterminate”。視覚と状態を分けて管理すると、直感的でバグが減ります。
相互排他の「トグル一択」を checkbox で再現
<label><input class="solo" type="checkbox" value="A">A</label>
<label><input class="solo" type="checkbox" value="B">B</label>
<script>
const boxes = [...document.querySelectorAll(".solo")];
boxes.forEach(b => b.addEventListener("change", () => {
if (b.checked) boxes.forEach(o => { if (o !== b) o.checked = false; });
}));
</script>
HTMLここが重要です:見た目はチェックボックスでも、同時に一つだけ選べる挙動を作れます。実態はラジオに近い仕様ですが、柔らかい UI が必要なときに使えます。
フォーム送信と検証(必須・エラー表示・存在判定)
必須チェックとエラーメッセージ
<form id="f">
<label><input id="agree" name="agree" type="checkbox">規約に同意</label>
<button>送信</button>
</form>
<script>
f.addEventListener("submit", (e) => {
if (!agree.checked) {
e.preventDefault();
alert("送信には同意が必要です");
}
});
</script>
HTMLここが重要です:必須条件は checked を見るのがシンプル。送信相当の確認には FormData.has(“agree”) を使っても正確です(未チェックはキーなし)。
FormData で存在判定(サーバーと同じ見え方)
<script>
const fd = new FormData(f);
const agreed = fd.has("agree"); // true/false
</script>
HTMLここが重要です:checked を見るのと等価ですが、サーバーと同じ“送信パケットの視点”で判定できるため、仕様の整合が保ちやすいです。
よくある落とし穴と回避策
value と checked の混同
value は送る文字列、checked は状態。未チェック時は value では判定できません。存在判定(checked か FormData.has)を使う。
multiple な checkbox を単一値として扱ってしまう
複数選択は配列で扱います。FormData.getAll(“name”) で全選択の値を取得するか、DOM を列挙して checked のものを集めます。
indeterminate を“選択状態”だと思い込む
indeterminate は視覚だけ。送信やロジック上は未選択扱い。表示とロジックを分離して考える。
プログラム変更でイベントが発火しない
コードで checked を変えた後に処理が必要なら、dispatchEvent で change を明示発火する。
ラジオを単一 input として参照して空振り
同じ name の集合で RadioNodeList を扱い、group.value で選択値を取得する。個別操作は checked を true にするだけで他が外れる。
まとめ
checked は checkbox と radio の「選択状態」を表す中核プロパティで、値(value)とは役割が異なります。checkbox は未チェックだと送信に含まれないため、存在判定が要点。radio は name グループで扱い、RadioNodeList.value が最短ルートです。UI ではマスター選択に indeterminate を活用し、イベントは input/change を目的に応じて使い分け、プログラム変更時は明示発火で同期する。これらを押さえれば、初心者でも読みやすく壊れにくい「checked の操作」を自信をもって実装できます。
