JavaScript | DOM 操作:属性操作 – checked

JavaScript
スポンサーリンク

checked とは何か

checked は「チェックボックスやラジオボタンの“選択状態”」を表します。ここが重要です:HTMLの checked 属性は“初期状態”を示し、JavaScript の el.checked プロパティは“現在の状態”を示します。初期と現在を混同しないことが、正しいフォーム制御の第一歩です。


属性とプロパティの違い(初期値 vs 現在値)

初期値は属性、現在値はプロパティ

<input id="agree" type="checkbox" checked>
<script>
  const el = document.getElementById("agree");
  console.log(el.getAttribute("checked")); // ""(属性:初期に付いている)
  console.log(el.checked);                 // true(プロパティ:今の状態)
  el.checked = false;                      // 今の状態をオフにする(画面が変わる)
  console.log(el.getAttribute("checked")); // "" のまま(初期設定は変わらない)
</script>
HTML

ここが重要です:今のオン/オフを変えるなら el.checked を操作します。el.setAttribute(“checked”,”false”) のような“文字列の false”は無効化できません(属性が“存在すると真”だから)。

初期値を動的に変えるなら defaultChecked

<input id="news" type="checkbox" checked>
<script>
  const news = document.getElementById("news");
  news.defaultChecked = false; // reset で戻る先(初期状態)を更新
  // news.checked は現在値。必要なら別途変更する
</script>
HTML

ここが重要です:フォームの reset 時に戻る「初期状態」を変えたいときは defaultChecked。現在の表示を変えたいときは checked。


チェックボックスの基本(checked と value を分ける)

オン/オフは checked、送信文字は value

<input id="optin" type="checkbox" value="yes">
<script>
  const optin = document.getElementById("optin");
  optin.checked = true;        // オンにする
  console.log(optin.value);    // "yes"(選ばれたとき送られるラベル)
</script>
HTML

ここが重要です:状態判定に value を使わない。オン/オフは常に checked で管理します。

複数チェックを集めて送る

<form id="f">
  <label><input name="tag" type="checkbox" value="news">ニュース</label>
  <label><input name="tag" type="checkbox" value="tech" checked>テック</label>
</form>
<script>
  const tags = Array.from(document.querySelectorAll('input[name="tag"]:checked'))
                     .map(el => el.value);
  console.log(tags); // ["tech"]
</script>
HTML

ここが重要です::checked で“選択中だけ”を取るのが最短。送る値は .value の配列にします。


ラジオボタンの基本(グループでひとつだけ選ぶ)

グループ名(name)で排他選択

<label><input type="radio" name="size" value="S">S</label>
<label><input type="radio" name="size" value="M" checked>M</label>
<label><input type="radio" name="size" value="L">L</label>
<script>
  const sel = document.querySelector('input[name="size"]:checked');
  console.log(sel?.value); // "M"
</script>
HTML

ここが重要です:name が同じラジオは“ひとつだけ”が選ばれる仕様。プログラムで切り替えるときは対象 .checked = true を付ければ他は自動で外れます。

プログラムで選択を切り替える

function choose(name, value) {
  const el = document.querySelector(`input[name="${name}"][value="${value}"]`);
  if (el) el.checked = true;
}
choose("size", "L");
JavaScript

ここが重要です:存在しない value を選ぼうとすると何も起きないため、候補を必ず確認してから切り替えます。


スタイルとセレクタ(:checked と見た目の同期)

CSS で選択状態にスタイル

<style>
  input[type="checkbox"]:checked + .label { font-weight: bold; }
</style>
<label>
  <input id="sub" type="checkbox">
  <span class="label">購読する</span>
</label>
<script>
  document.getElementById("sub").checked = true; // スタイルも即同期
</script>
HTML

ここが重要です:JS で checked を切り替えれば、:checked 擬似クラスが自動で反映されます。視覚と状態のズレが起きません。


イベントとアクセシビリティ(change・aria と同期)

change で“確定後”の状態を扱う

<input id="agree" type="checkbox">
<script>
  const agree = document.getElementById("agree");
  agree.addEventListener("change", () => {
    console.log("現在:", agree.checked);
  });
</script>
HTML

ここが重要です:チェックボックス/ラジオは change が自然。プログラムで値を変えたあとに通知したいなら、必要に応じて dispatchEvent(new Event(“change”)) を明示します。

カスタムトグルは aria-checked を揃える

<div id="toggle" role="switch" aria-checked="false" tabindex="0">通知</div>
<script>
  const t = document.getElementById("toggle");
  function setOn(on) {
    t.setAttribute("aria-checked", String(on));
    t.classList.toggle("is-on", on);
  }
  t.addEventListener("click", () => setOn(t.getAttribute("aria-checked") !== "true"));
</script>
HTML

ここが重要です:ネイティブの input を使わない“見た目だけのスイッチ”は、aria-checked とキーボード操作の対応(Enter/Space)も実装してアクセシビリティを保ちます。


便利な特性と落とし穴(indeterminate・reset・属性誤用)

indeterminate(チェックでも未チェックでもない“中間”)

<input id="master" type="checkbox">
<script>
  const m = document.getElementById("master");
  m.indeterminate = true; // 見た目を“中間”にできる(送信値や checked は変わらない)
</script>
HTML

ここが重要です:親チェックボックスの“部分選択”表示に使えます。論理状態は自前で決め、indeterminate は見た目の補助です。

reset の戻り先は defaultChecked

<form id="f">
  <input id="opt" type="checkbox" checked>
  <button type="reset">リセット</button>
</form>
<script>
  const opt = document.getElementById("opt");
  opt.checked = false;              // 今は OFF
  document.getElementById("f").reset(); // 初期の ON に戻る
  opt.defaultChecked = false;       // 次回の reset では OFF に戻るように更新
</script>
HTML

ここが重要です:初期と現在を分けることで、フォームの“戻り方”をコントロールできます。

checked 属性を文字列で制御しない

<input id="x" type="checkbox" checked>
<script>
  const x = document.getElementById("x");
  x.setAttribute("checked", "false"); // NG:属性が“存在”するため ON のまま
  x.removeAttribute("checked");       // 初期設定を外す(現在は変わらない)
  x.checked = false;                  // 現在状態をオフにする(見た目が変わる)
</script>
HTML

ここが重要です:boolean 属性は“有無が真偽”。現在値は .checked で操作します。


実践例(全選択・部分選択、同期、送信整形)

子項目の全選択・部分選択を同期

<input id="all" type="checkbox"> 全選択
<div id="list">
  <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 all = document.getElementById("all");
  const items = Array.from(document.querySelectorAll(".item"));

  function syncMaster() {
    const on = items.every(i => i.checked);
    const off = items.every(i => !i.checked);
    all.checked = on;
    all.indeterminate = !on && !off; // 部分選択
  }
  all.addEventListener("change", () => {
    items.forEach(i => i.checked = all.checked);
    syncMaster();
  });
  items.forEach(i => i.addEventListener("change", syncMaster));
  syncMaster();
</script>
HTML

ここが重要です:checked と indeterminate を組み合わせると、直感的でわかりやすい全選択 UI を作れます。

送信前に選択値を配列へ整形

function checkedValues(name) {
  return Array.from(document.querySelectorAll(`input[name="${name}"]:checked`))
              .map(el => el.value);
}
console.log(checkedValues("tag")); // ["news","tech"] など
JavaScript

ここが重要です:サーバーが期待する形式に“常に同じルール”で整形すると、後工程が安定します。


まとめ

checked は「選択状態」を扱う中心概念です。初期値は属性(checked/defaultChecked)、現在値はプロパティ(el.checked)。状態は必ず checked で管理し、送信する文字は value。ラジオは name で排他、CSS の :checked で見た目と同期、カスタム UI は aria-checked を揃える。indeterminate と reset を理解して、初期と現在を明確に分離すれば、初心者でも意図通りで壊れにくい選択制御が書けます。

タイトルとURLをコピーしました