JavaScriptで自作スライダーを作成する7手順

JavaScriptのquerySelectorAllを使った複数要素の取得JS
この記事は約22分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●querySelectorAllとは?

今回は、JavaScriptのquerySelectorAllについて詳しく解説していきます。

querySelectorAllは、HTMLドキュメント内の要素を効率的に取得するためのメソッドです。

これを使いこなせば、Webサイトのフロントエンド開発がぐっと楽になるでしょう。

まずは、querySelectorAllの基本的な使い方から見ていきましょう。

querySelectorAllは、CSSセレクターを使ってHTMLの要素を取得します。

例えば、特定のクラス名を持つ要素をすべて取得したい場合は、次のように書きます。

○querySelectorAllの基本的な使い方

const elements = document.querySelectorAll('.class-name');

このコードでは、.class-nameというクラス名を持つ要素がすべて取得され、elementsという変数に格納されます。

取得された要素は、ノードリストと呼ばれるリスト形式で返されます。

○サンプルコード1:単一のクラス名による要素の取得

具体的なサンプルコードを見てみましょう。

次のHTMLがあるとします。

<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>

このとき、.boxクラスを持つ要素をすべて取得するには、次のようにします。

const boxes = document.querySelectorAll('.box');
console.log(boxes.length); // 3

取得された要素の数はboxes.lengthで確認できます。

この場合は3つの要素が取得されているので、3が出力されます。

○サンプルコード2:複数のクラス名による要素の取得

次に、複数のクラス名を指定して要素を取得する方法を見てみましょう。

<div class="box red">Red Box</div>
<div class="box blue">Blue Box</div>
<div class="box green">Green Box</div>

この場合、.boxクラスと.redクラスの両方を持つ要素を取得するには、次のようにします。

const redBoxes = document.querySelectorAll('.box.red');
console.log(redBoxes.length); // 1

○querySelectorAllとquerySelectorの違い

ここで、querySelectorAllとquerySelectorの違いについても触れておきましょう。

querySelectorは、指定したセレクターに一致する最初の要素を返すのに対し、querySelectorAllは一致するすべての要素を返します。

単一の要素だけが必要な場合は、querySelectorを使うのが適しています。

●querySelectorAllの応用

前回は、querySelectorAllの基本的な使い方について解説しました。

クラス名を指定して要素を取得する方法や、querySelectorAllとquerySelectorの違いについて理解が深まったのではないでしょうか。

今回は、さらに一歩進んで、querySelectorAllのより応用的な使い方に挑戦していきましょう。

○サンプルコード3:属性セレクターによる要素の取得

まずは、属性セレクターを使った要素の取得方法から見ていきます。

属性セレクターとは、要素の属性値に基づいて要素を選択するためのセレクターです。

例えば、特定の属性を持つ要素だけを取得したい場合に便利です。

<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="Login">

上記のようなHTMLがあるとき、type属性がtextであるinput要素を取得するには、次のようにします。

const textInputs = document.querySelectorAll('input[type="text"]');
console.log(textInputs.length); // 1

この場合、type属性がtextであるinput要素が1つだけ取得されます。

属性セレクターを使えば、特定の属性を持つ要素を絞り込んで取得できるので、とても便利ですね。

○サンプルコード4:子要素や孫要素の取得

次に、子要素や孫要素の取得方法を見ていきましょう。

querySelectorAllを使えば、特定の要素の下にある子要素や孫要素を簡単に取得できます。

<div class="parent">
  <div class="child">
    <div class="grandchild"></div>
  </div>
  <div class="child">
    <div class="grandchild"></div>
  </div>
</div>

上記のようなHTMLがあるとき、parentクラスを持つ要素の下にあるgrandchildクラスを持つ要素をすべて取得するには、次のようにします。

const parent = document.querySelector('.parent');
const grandchildren = parent.querySelectorAll('.grandchild');
console.log(grandchildren.length); // 2

まず、parentクラスを持つ要素を取得し、その要素に対してquerySelectorAllを使ってgrandchildクラスを持つ要素を取得しています。

これにより、parentの下にある全てのgrandchildが取得できました。

○サンプルコード5:特定の要素の除外

続いて、特定の要素を除外して取得する方法を見ていきます。

not()セレクターを使うことで、特定の条件に一致しない要素を取得できます。

<div class="box">Box 1</div>
<div class="box exclude">Box 2</div>
<div class="box">Box 3</div>

上記のようなHTMLがあるとき、excludeクラスを持つ要素以外のboxクラスを持つ要素を取得するには、次のようにします。

const boxes = document.querySelectorAll('.box:not(.exclude)');
console.log(boxes.length); // 2

not()セレクターの中で.excludeを指定することで、excludeクラスを持つ要素が除外され、Box 1とBox 3の2つの要素が取得されました。

特定の要素を除外したい場合に、not()セレクターは大変便利です。

○サンプルコード6:取得した要素へのスタイル適用

最後に、取得した要素にスタイルを適用する方法を見ていきましょう。

querySelectorAllで取得した要素は、ノードリストとして返されます。

このノードリストに対して、forEachを使ってループ処理を行うことで、各要素にスタイルを適用できます。

<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>

上記のようなHTMLに対して、boxクラスを持つ要素の背景色を変更するには、次のようにします。

const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
  box.style.backgroundColor = 'blue';
});

取得したboxクラスを持つ要素に対してforEachを使ってループ処理を行い、各要素のbackgroundColorプロパティを変更しています。

これにより、全てのboxの背景色が青色に変更されます。

●よくあるエラーと対処法

さて、ここまでquerySelectorAllの基本的な使い方から応用的な使い方まで見てきましたが、実際にコードを書いていると、思わぬエラーに遭遇することがあります。

特に、JavaScriptを学び始めたばかりの頃は、エラーメッセージを見ても何が原因なのかわからず、途方に暮れてしまうこともあるでしょう。

そこで今回は、querySelectorAllを使う際によく発生するエラーとその対処法について解説していきます。

エラーに遭遇しても、あわてず対処できるようになれば、JavaScriptの学習もぐっと楽しくなるはずです。

○要素が取得できない場合の確認事項

querySelectorAllを使っているのに、思ったように要素が取得できない場合、まず確認したいのがセレクターの指定方法です。

クラス名やid、属性セレクターなど、セレクターの指定に誤りがないかを確認しましょう。

特に、クラス名やidの大文字小文字の違いや、属性値の引用符の有無などは、よく見落としがちなポイントです。

また、querySelectorAllを実行するタイミングにも注意が必要です。

HTMLのパース前にquerySelectorAllを実行しようとすると、要素が取得できません。

HTMLのパースが完了してから実行するか、DOMContentLoadedイベントなどを使って適切なタイミングで実行するようにしましょう。

document.addEventListener('DOMContentLoaded', function() {
  const elements = document.querySelectorAll('.example');
  console.log(elements.length);
});

上記のように、DOMContentLoadedイベントを使えば、HTMLのパースが完了した後にquerySelectorAllを実行できます。

○ノードリストとHTMLCollectionの違い

querySelectorAllが返すノードリストと、getElementByTagNameなどが返すHTMLCollectionは、どちらも複数の要素を含むコレクションですが、それぞれ異なる特徴を持っています。

ノードリストは、要素の追加や削除に合わせてリアルタイムに更新されません。

一方、HTMLCollectionは要素の追加や削除に合わせてリアルタイムに更新されます。

この違いを理解しておかないと、思わぬバグに遭遇する可能性があります。

const elements = document.querySelectorAll('.example');
console.log(elements.length); // 3

const newElement = document.createElement('div');
newElement.classList.add('example');
document.body.appendChild(newElement);

console.log(elements.length); // 3(更新されない)

上記のように、ノードリストは要素の追加後も更新されないため、length属性の値は変わりません。

HTMLCollectionの場合は、要素の追加後にlength属性の値が更新されます。

○パフォーマンスを考慮した使用方法

querySelectorAllは非常に便利なメソッドですが、大量の要素を取得する場合はパフォーマンスに注意が必要です。

querySelectorAllは、指定されたセレクターに一致する全ての要素を取得するため、HTMLドキュメントの規模が大きい場合は処理に時間がかかってしまいます。

パフォーマンスを考慮する場合は、できるだけ具体的なセレクターを指定して、不要な要素を取得しないようにしましょう。

また、何度も同じ要素を取得する場合は、一度取得した要素を変数に格納しておくことで、再度querySelectorAllを実行する必要がなくなります。

// 非効率的な例
document.querySelectorAll('.example').forEach(el => {
  el.classList.add('active');
});

document.querySelectorAll('.example').forEach(el => {
  el.addEventListener('click', function() {
    console.log('clicked');
  });
});

// 効率的な例
const elements = document.querySelectorAll('.example');

elements.forEach(el => {
  el.classList.add('active');
});

elements.forEach(el => {
  el.addEventListener('click', function() {
    console.log('clicked');
  });
});

上記のように、一度querySelectorAllで取得した要素を変数に格納しておけば、何度も同じ要素を取得する必要がなくなり、パフォーマンスの向上につながります。

●querySelectorAllの実践的な使用例

これまで、querySelectorAllの基本的な使い方から応用的な使い方、よくあるエラーと対処法まで見てきました。

JavaScriptを学び始めたばかりの方にとっては、少し難しい内容もあったかもしれませんね。

でも、これらを理解することで、より効率的で柔軟なDOM操作ができるようになります。

さて、ここからは、querySelectorAllをより実践的なシーンで活用する方法について見ていきましょう。

実際の開発現場では、フォームの入力値を一括で取得したり、テーブルのソート機能を実装したりと、querySelectorAllが大活躍します。

具体的なサンプルコードを交えながら、一緒に学んでいきましょう。

○サンプルコード7:フォーム入力値の一括取得

Webサイトでは、ユーザーからの情報を入力させるためのフォームを用意することが一般的です。

フォームの送信ボタンがクリックされたときに、入力された値を一括で取得したい場合、querySelectorAllを使うと便利です。

<form id="myForm">
  <input type="text" name="name" placeholder="Name">
  <input type="email" name="email" placeholder="Email">
  <textarea name="message" placeholder="Message"></textarea>
  <button type="submit">Submit</button>
</form>

上記のようなフォームがあるとします。

フォームの送信イベントを監視し、入力値を取得するには、次のようにします。

const form = document.querySelector('#myForm');

form.addEventListener('submit', function(e) {
  e.preventDefault(); // フォームのデフォルトの送信を防ぐ

  const inputs = form.querySelectorAll('input, textarea');
  const values = {};

  inputs.forEach(input => {
    values[input.name] = input.value;
  });

  console.log(values);
});

querySelectorAllを使って、フォーム内のすべてのinputとtextarea要素を取得しています。

取得した要素をforEachでループ処理し、name属性とvalue属性を取得して、valuesオブジェクトに格納しています。

これにより、フォームの入力値を一括で取得できます。

○サンプルコード8:テーブルのソート機能の実装

Webアプリケーションでは、テーブルに表示されたデータをソートする機能があると便利ですよね。

querySelectorAllを使えば、テーブルのヘッダーをクリックしたときに、該当する列のデータをソートする機能を簡単に実装できます。

<table id="myTable">
  <thead>
    <tr>
      <th data-sort="string">Name</th>
      <th data-sort="number">Age</th>
      <th data-sort="string">Email</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John Doe</td>
      <td>30</td>
      <td>john@example.com</td>
    </tr>
    <tr>
      <td>Jane Smith</td>
      <td>25</td>
      <td>jane@example.com</td>
    </tr>
    <!-- more rows... -->
  </tbody>
</table>

上記のようなテーブルがあるとします。

各th要素にdata-sort属性を付与し、ソートするデータの型を指定しています。

const table = document.querySelector('#myTable');
const headers = table.querySelectorAll('th');

headers.forEach(header => {
  header.addEventListener('click', function() {
    const sortType = this.dataset.sort;
    const index = Array.from(headers).indexOf(this);
    const rows = table.querySelectorAll('tbody tr');

    const sortedRows = Array.from(rows).sort((a, b) => {
      const aValue = a.children[index].textContent;
      const bValue = b.children[index].textContent;

      if (sortType === 'number') {
        return aValue - bValue;
      } else {
        return aValue.localeCompare(bValue);
      }
    });

    table.querySelector('tbody').innerHTML = '';
    sortedRows.forEach(row => {
      table.querySelector('tbody').appendChild(row);
    });
  });
});

querySelectorAllを使って、テーブルのヘッダー(th要素)とボディの行(tr要素)を取得しています。

ヘッダーのクリックイベントを監視し、クリックされたヘッダーのインデックスと、data-sort属性の値を取得します。

取得した行を配列に変換し、ソートします。ソートの際は、該当する列のデータを比較します。

data-sort属性の値に応じて、数値比較か文字列比較を行います。

ソート後の行をtbody要素に追加することで、テーブルのソートが完了します。

querySelectorAllとデータ属性を組み合わせることで、テーブルのソート機能を柔軟に実装できました。

○サンプルコード9:アコーディオンメニューの作成

アコーディオンメニューは、項目をクリックすると、その項目に関連するコンテンツが展開されるUIパターンです。

querySelectorAllを使えば、アコーディオンメニューを簡単に作成できます。

<div class="accordion">
  <div class="accordion-item">
    <div class="accordion-header">Header 1</div>
    <div class="accordion-content">
      <p>Content 1</p>
    </div>
  </div>
  <div class="accordion-item">
    <div class="accordion-header">Header 2</div>
    <div class="accordion-content">
      <p>Content 2</p>
    </div>
  </div>
  <!-- more items... -->
</div>

上記のようなアコーディオンメニューのHTMLがあるとします。

各項目は.accordion-itemクラスを持ち、ヘッダーは.accordion-header、コンテンツは.accordion-contentクラスを持っています。

const accordion = document.querySelector('.accordion');
const headers = accordion.querySelectorAll('.accordion-header');

headers.forEach(header => {
  header.addEventListener('click', function() {
    const item = this.parentElement;
    const content = item.querySelector('.accordion-content');

    item.classList.toggle('active');

    if (item.classList.contains('active')) {
      content.style.maxHeight = content.scrollHeight + 'px';
    } else {
      content.style.maxHeight = '0';
    }
  });
});

querySelectorAllを使って、アコーディオンメニューのヘッダー要素をすべて取得します。

ヘッダーのクリックイベントを監視し、クリックされた項目に.activeクラスを付与または削除することで、項目の開閉を切り替えます。

コンテンツの高さをCSSのmaxHeightプロパティで制御することで、アニメーションを伴った開閉動作を実現しています。

querySelectorAllとCSSを組み合わせることで、インタラクティブなUIコンポーネントを手軽に作成できます。

○サンプルコード10:ギャラリーの動的な生成

画像ギャラリーを動的に生成する際にも、querySelectorAllが活躍します。

あらかじめ用意した画像のURLの配列から、ギャラリーを動的に生成してみましょう。

const images = [
  'image1.jpg',
  'image2.jpg',
  'image3.jpg',
  // more image URLs...
];

const gallery = document.querySelector('.gallery');
const template = document.querySelector('#gallery-item');

images.forEach(imageUrl => {
  const clone = template.content.cloneNode(true);
  clone.querySelector('img').src = imageUrl;
  gallery.appendChild(clone);
});

const items = gallery.querySelectorAll('.gallery-item');

items.forEach(item => {
  item.addEventListener('click', function() {
    const imageUrl = this.querySelector('img').src;
    const modal = document.createElement('div');
    modal.classList.add('modal');
    modal.innerHTML = `
      <div class="modal-content">
        <img src="${imageUrl}" alt="">
      </div>
    `;
    document.body.appendChild(modal);

    modal.addEventListener('click', function() {
      this.remove();
    });
  });
});

まず、画像のURLの配列imagesを用意します。

次に、テンプレート要素を使って、ギャラリーのアイテムを動的に生成します。

querySelectorを使ってテンプレートを取得し、cloneNodeメソッドでテンプレートの内容を複製します。

複製したテンプレートのimg要素のsrc属性に、画像のURLを設定し、ギャラリー要素に追加します。

これを画像の数だけ繰り返すことで、ギャラリーが動的に生成されます。

生成されたギャラリーのアイテムに対して、querySelectorAllを使ってクリックイベントを設定します。

アイテムがクリックされたら、モーダルウィンドウを表示し、クリックされた画像を拡大表示します。

まとめ

JavaScriptのquerySelectorAllは、CSSセレクターを使って複数の要素を取得するための強力なメソッドです。

この記事では、querySelectorAllの基本的な使い方から応用的な使い方、実践的な使用例まで、幅広く解説してきました。

querySelectorAllは、JavaScriptでDOM操作を行う上で欠かせないメソッドの一つです。

この記事で学んだ知識を活かして、より効率的で柔軟なコーディングを目指してみてください。

初めは難しく感じるかもしれませんが、練習を重ねることでどんどん上達していくはずです。

これからもJavaScriptの学習を続け、Webデザイナーとしてのスキルを磨いていきましょう。

将来的には、より複雑なWebアプリケーションの開発にも挑戦してみてください。

querySelectorAllを使いこなせば、きっとあなたのコーディングの幅が広がるはずです。

頑張ってください!