[PR] 本記事にはプロモーションが含まれています。

【JavaScript】querySelectorで使えるCSSセレクターの書き方|基本・属性・結合子・疑似クラスのチートシートと注意点

JavaScript

JavaScriptでHTMLの要素を取得するときによく使うのが、document.querySelector() です。引数にはCSSと同じ書き方(セレクター)を使えるので、CSSを少し書いたことがあれば、その知識をそのまま活かせます。

この記事では、querySelector と querySelectorAll に渡すセレクターの書き方を種類ごとにまとめ、使うときにつまずきやすい点も紹介します。

querySelector と querySelectorAll の違い

メソッド戻り値見つからないとき
querySelector()条件に合う最初の1つの要素null
querySelectorAll()条件に合うすべての要素(NodeList)空の NodeList(件数0)

1つだけ欲しいときは querySelector、まとめて処理したいときは querySelectorAll を使います。セレクターの書き方はどちらも同じです。

基本のセレクター

種類記号書き方の例取得できる要素
要素(タグ)なし'div'<div> 要素
ID#'#app'id="app" の要素
クラス.'.btn'class に btn を含む要素(class="btn primary" も対象)
組み合わせつなげて書く'button.btn.primary'class に btn と primary の両方を含む <button>
JavaScript
const header = document.querySelector('header');
const title = document.querySelector('#title');
const submitButton = document.querySelector('.submit-btn');

属性で指定する(属性セレクター)

type や href、自分で付けられる data-* 属性などで絞り込めます。フォームの部品を取得するときによく使います。

条件書き方の例取得できる要素
属性がある'[disabled]'disabled 属性が付いている要素
値が一致'[type="text"]'type が text の要素
値が〜で始まる'[href^="https"]'href が https で始まる要素
値が〜で終わる'[src$=".png"]'src が .png で終わる要素
値に〜を含む'[class*="icon-"]'class の文字列に icon- を含む要素
JavaScript
// チェックボックスを取得
const checkbox = document.querySelector('input[type="checkbox"]');

// data-status="active" が付いた要素を取得
const activeTab = document.querySelector('[data-status="active"]');

セレクターの中で " を使うので、外側を ' で囲むとエスケープがいりません。クォートの使い分けは「文字列の ‘ と ” と ` の違い」で紹介しています。

親子や兄弟の関係で指定する(結合子)

HTMLの入れ子の関係を使って、目的の要素を絞り込みます。

種類記号書き方の例取得できる要素
子孫(中にあるものすべて)半角スペース'ul li'<ul> の中にある <li>(入れ子の奥も含む)
子(すぐ下だけ)>'ul > li'<ul> のすぐ下にある <li>
すぐ後ろの兄弟+'h2 + p'<h2> のすぐ後ろにある <p>
後ろにある兄弟~'h2 ~ p'<h2> より後ろにある、同じ親の <p>
JavaScript
// .nav-menu のすぐ下の li の、すぐ下の a を取得
const navLink = document.querySelector('.nav-menu > li > a');

状態や順番で指定する(疑似クラス)

種類書き方の例取得できる要素
最初の子'li:first-child'親の中で最初の子である <li>
最後の子'li:last-child'親の中で最後の子である <li>
n番目の子'li:nth-child(3)'親の中で3番目の子である <li>
〜以外'div:not(.hidden)'class に hidden を含まない <div>
チェック済み'input:checked'チェックが入っているチェックボックスやラジオボタン
JavaScript
// チェックが入っているラジオボタン(name="plan")を取得
const selected = document.querySelector('input[name="plan"]:checked');

// .is-hidden が付いていないエラーメッセージを取得
const visibleError = document.querySelector('.error-msg:not(.is-hidden)');

nth-child の勘違いに注意

.list-item:nth-child(2) は「2番目の .list-item」ではなく、「親の中で2番目の子で、かつ .list-item である要素」を指します。たとえば次のHTMLでは、結果が変わります。

HTML
<ul>
  <li class="note">お知らせ</li>
  <li class="list-item">項目1</li>
  <li class="list-item">項目2</li>
</ul>
JavaScript
// 親の中で2番目の子(かつ .list-item)→「項目1」
console.log(document.querySelector('.list-item:nth-child(2)').textContent);

// 2番目の .list-item →「項目2」
console.log(document.querySelectorAll('.list-item')[1].textContent);

「○番目の .list-item」が欲しいときは、querySelectorAll でまとめて取得してから番号(0から数える)で選ぶと確実です。

複数のセレクターをまとめて指定する

カンマ , で区切ると、「A または B」に当てはまる要素をまとめて取得できます。取得される順番は、書いた順ではなく、HTMLの中で並んでいる順です。

JavaScript
// h1、h2、h3 をまとめて取得(HTMLの中の順)
const headings = document.querySelectorAll('h1, h2, h3');

// .btn-primary または .btn-secondary をまとめて取得
const buttons = document.querySelectorAll('.btn-primary, .btn-secondary');

使うときにつまずきやすいこと

見つからないと null になる

querySelector は、要素が見つからないと null を返します。そのまま使うと「Cannot read properties of null」のエラーになるので、ないかもしれない要素は確かめてから使います。

JavaScript
const button = document.querySelector('.submit-btn');

if (button) {
  button.addEventListener('click', () => {
    console.log('送信');
  });
}

<script> を <head> に書いていると、HTMLの要素がまだ読み込まれていなくて null になることもあります。<script defer src="..."> のように defer を付けるか、</body> の直前に書くと防げます。

querySelectorAll の戻り値は配列ではない

querySelectorAll が返すのは NodeList で、配列とは少し違います。forEach や length、[0] のような番号での取り出しは使えますが、map や filter はそのままでは使えません。使いたいときは Array.from() で配列に変えます。

JavaScript
const items = document.querySelectorAll('li');

items.forEach(item => console.log(item.textContent)); // OK

// items.map(...) はエラーになるので、配列に変えてから使う
const texts = Array.from(items).map(item => item.textContent);

filter の書き方は「filterメソッドの書き方」で紹介しています。

要素の中だけを探す

querySelector は document だけでなく、取得した要素からも呼べます。その要素の中だけを探すので、同じクラスがページのあちこちにあるときに便利です。

JavaScript
const nav = document.querySelector('.nav-menu');
const navLinks = nav.querySelectorAll('a'); // .nav-menu の中の a だけ

書き間違いや特殊な文字はエラーになる

セレクターの書き方が間違っていると、null ではなく SyntaxError になります。数字で始まる id も、そのまま # を付けるとエラーになるので注意が必要です。

JavaScript
// document.querySelector('#1st'); // SyntaxError(数字で始まる id)

const el1 = document.querySelector('#' + CSS.escape('1st')); // CSS.escape で変換する
const el2 = document.getElementById('1st');                   // id だけならこちらでもよい

id だけで取得するなら getElementById も使えます。# を付けずに id をそのまま渡すので、このような変換もいりません。

疑似要素は取得できない

CSSの ::before や ::after のような疑似要素は、HTMLの要素ではないので querySelector では取得できません。CSSと同じ書き方といっても、取得できるのはHTMLの要素だけです。

まとめ

  • querySelector は最初の1つ(なければ null)、querySelectorAll はすべて(NodeList)を返す
  • セレクターは、タグ・id・クラス、属性、親子・兄弟の関係、状態や順番で組み合わせられる
  • :nth-child(n) は「親の中でn番目の子」。「n番目の○○」なら querySelectorAll()[n - 1]
  • null の確認、NodeList と配列の違い、数字で始まる id に気をつける

この記事のコードは、CodePenなどでHTMLと一緒に試すと、どの要素が取得されるかがよく分かります。取得した要素の値がないときのデフォルト値の入れ方は、「??(Null合体演算子)と三項演算子の違い」で紹介しています。

ほかの開発・プログラミングの記事は、開発・プログラミングメモの目次から、テーマ別に探せます。

このブログは、にほんブログ村と人気ブログランキングに参加しています。記事が役に立ったら、下のランキングのバナーのどれかを押して応援してもらえると励みになります。

ブログランキング・にほんブログ村へにほんブログ村

サーバー構築・運用ランキング プログラムランキング

JavaScript
watasoftdevをフォローする

コメント