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

JavaScript
スポンサーリンク

hasAttribute とは何か

hasAttribute は、要素に指定した「属性が付いているか」を true/false で判定するメソッドです。値が空文字でも、属性が存在していれば true になります。ここが重要です:getAttribute が返す “文字列 or null” に依存せず、純粋に「存在」のみを確認できるため、分岐がシンプルで安全です。


基本の使い方(存在判定の最短ルート)

<a id="link" href="/help" title="ヘルプ">ヘルプ</a>
<script>
  const a = document.getElementById("link");
  console.log(a.hasAttribute("href"));     // true
  console.log(a.hasAttribute("download")); // false(付いていない)
</script>
HTML

属性が存在するかどうかだけを知りたい場合は hasAttribute を使います。ここが重要です:値の中身(空かどうか)の判定は別で行い、まず“あるかないか”をはっきりさせるとロジックが読みやすくなります。


getAttribute との違い(null 判定より明快)

<button id="btn" data-count="0">購入</button>
<script>
  const btn = document.getElementById("btn");
  // 存在だけチェック(0 でも true)
  console.log(btn.hasAttribute("data-count"));      // true
  // 値を読むときは getAttribute(未設定なら null)
  console.log(btn.getAttribute("data-missing"));    // null
</script>
HTML

getAttribute は文字列か null を返すため、0 や空文字を「未設定」と誤判定しがちです。ここが重要です:存在判定は hasAttribute、値の取得は getAttribute。役割を分けるとバグが減ります。


boolean 属性の正しい判定(存在が真)

<input id="agree" type="checkbox" checked>
<script>
  const el = document.getElementById("agree");
  console.log(el.hasAttribute("checked")); // true(存在で判定)
  console.log(el.checked);                 // true(プロパティ:現在の状態)
</script>
HTML

disabled、checked、required などの boolean 属性は「付いていれば真」です。ここが重要です:初期設定の確認は hasAttribute、現在のオン/オフはプロパティ(el.disabled / el.checked)で見る。混同すると、ユーザー操作後の状態を誤解します。


安全な分岐パターン(未設定と設定済みを明確に扱う)

<img id="avatar" alt="プロフィール写真">
<script>
  const img = document.getElementById("avatar");
  if (!img.hasAttribute("src")) {
    // 未設定ならプレースホルダーを設定
    img.setAttribute("src", "/assets/placeholder.png");
  }
}
</script>
HTML

「未設定なら補う、設定済みなら尊重する」という分岐は hasAttribute で明快に書けます。ここが重要です:空文字を“設定済み”とみなす設計かどうかも、プロジェクトで取り決めておくと一貫します。


data-* と JSON の取り扱い(存在→取り出し→パース)

<button id="item" data-payload='{"id":7,"tags":["new"]}'>購入</button>
<script>
  const el = document.getElementById("item");
  if (el.hasAttribute("data-payload")) {
    const raw = el.getAttribute("data-payload");
    const payload = JSON.parse(raw);
    console.log(payload.id); // 7
  }
}
</script>
HTML

data-* は文字列専用なので、存在判定→文字列取得→JSON.parse の流れが定石です。ここが重要です:存在チェックを先に行うと、null を誤って JSON.parse して例外になる事故を防げます。


ARIA とアクセシビリティ(関係の有無を正しく判断)

<button id="toggle" aria-controls="panel" aria-expanded="false">開く</button>
<div id="panel">内容</div>
<script>
  const btn = document.getElementById("toggle");
  if (btn.hasAttribute("aria-controls")) {
    const targetId = btn.getAttribute("aria-controls");
    const target = document.getElementById(targetId);
    // 関係があるときだけ操作を実行
    btn.addEventListener("click", () => {
      const next = btn.getAttribute("aria-expanded") !== "true";
      btn.setAttribute("aria-expanded", String(next));
      target.classList.toggle("is-hidden", !next);
    });
  }
}
</script>
HTML

ARIA のような「関係を示す属性」は、存在しない場合は処理自体をスキップするのが安全です。ここが重要です:hasAttribute で前提条件を満たすか確認し、満たさない場合は早期 return にすると堅牢になります。


CSS と属性セレクタの相互作用(消えるとスタイルが外れる)

<style>
  [data-state="error"] { color: red; }
</style>
<div id="msg" data-state="error">失敗しました</div>
<script>
  const msg = document.getElementById("msg");
  if (msg.hasAttribute("data-state")) {
    msg.removeAttribute("data-state"); // スタイルも外れる
  }
}
</script>
HTML

属性セレクタ([attr] や [attr=”値”])でスタイルを当てている場合、属性の有無で見た目が変わります。ここが重要です:hasAttribute で存在を確認したうえで removeAttribute すると、スタイルが外れることを前提に設計できます。


よくある落とし穴と対策(空文字・typo・DOMタイミング)

<input id="age" data-min="">
<script>
  const age = document.getElementById("age");

  // 空文字でも“存在”は true
  console.log(age.hasAttribute("data-min")); // true

  // 誤字は常に false
  console.log(age.hasAttribute("data-miin")); // false

  // 初期化タイミング(DOM がまだ無いと null)
  document.addEventListener("DOMContentLoaded", () => {
    const el = document.querySelector("#age");
    if (el && el.hasAttribute("data-min")) {
      // ここで安全に扱う
    }
  });
</script>
HTML

空文字は「存在する」ため true になります。ここが重要です:空文字を“未設定”とみなすかどうかを決め、必要なら値の非空チェックも併用する。また、typo は判定できないため、クラス名・属性名は定数化するとミスが減ります。


ユーティリティで標準化(存在チェック+既定値の読取)

function has(el, name) {
  return el?.hasAttribute(name) === true;
}
function read(el, name, fallback = "") {
  const v = el.getAttribute(name);
  return v == null ? fallback : v;
}

// 使い方
const link = document.getElementById("link");
if (has(link, "href")) {
  const href = read(link, "href");
  // 安全に利用
}
JavaScript

存在判定と読み取りを小さな関数にまとめると、コード全体で挙動が揃います。ここが重要です:null や undefined の扱いを統一し、例外や誤判定を根絶します。


実践例:条件付きで属性を付け外し(状態と同期)

<button id="mode" aria-pressed="false" class="btn">モード</button>
<script>
  const btn = document.getElementById("mode");
  btn.addEventListener("click", () => {
    const pressed = btn.getAttribute("aria-pressed") === "true";
    const next = !pressed;

    // 明示的に状態を設定
    btn.setAttribute("aria-pressed", String(next));

    // 依存する属性を存在で管理
    if (next && !btn.hasAttribute("title")) {
      btn.setAttribute("title", "ON です");
    } else if (!next && btn.hasAttribute("title")) {
      btn.removeAttribute("title"); // OFF ではツールチップ不要に戻す
    }

    btn.classList.toggle("is-on", next);
  });
</script>
HTML

状態と属性の存在を同期させると、読み上げ・ツールチップ・見た目の整合が保てます。ここが重要です:付ける条件/外す条件を hasAttribute で明確に分けると、意図が伝わるコードになります。


まとめ

hasAttribute は「その属性が付いているか」を完全一致で判定するメソッドです。値の中身ではなく“存在”に焦点を当てるため、boolean 属性の扱い、未設定と設定済みの分岐、ARIA の前提チェック、CSS 属性セレクタとの連動で強力に機能します。値の取得は getAttribute、現在の状態はプロパティ——役割を分け、空文字・typo・DOMタイミングへの対策を標準化すれば、初心者でも明快で安全な属性判定が書けます。

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