JS

ネイティブネタ帳

UI

モーダル

タブ

ドロワー

スライダー

スクロール

アコーディオン

目次

ローディングアニメーション

ツールチップ

ヘッダー

テーブル

グラフ

背景

ニュースティッカー

フォーム

フォーム

文字

文字の装飾

文字の操作

文字のカウント

数字の操作

ウィンドウ

ウィンドウ操作

タイトルの操作

ページ遷移時の動き

class

classの操作

要素

要素の操作

要素の追加

API

WP REST API

Google Books APIs

楽天市場API

openBD

画像・動画

画像の操作

YouTube

リンク

Google Analytics

cookie

検索

検索

お気に入り登録

JavaScriptの.nextElementSiblingでアコーディオンの開閉と画像の切り替え

お気に入り登録をすると、お気に入り記事一覧に登録することができます。

.nextElementSibling

JavaScriptの.nextElementSiblingでアコーディオンの開閉と画像の切り替え

JavaScriptの.nextElementSiblingでアコーディオンの開閉と画像の切り替え

この記事では、JavaScriptの.nextElementSiblingを使って、ユーザーがクリックしたアイテムの直後に位置する要素を操作することで、スムーズな開閉アニメーションと画像のロードを実現します。

簡潔なコードスニペットを交えながら、初心者でも理解しやすいようにポイントを押さえて説明します。

.nextElementSibling

JavaScriptの.nextElementSiblingは、DOM(Document Object Model)における特定の要素の直後に位置する兄弟要素を取得するために使用されます。

かかかず
かかかず

これにより、HTMLの構造をJavaScriptを使って動的に操作することができます。

たとえば、HTML内のリストアイテムがあり、特定のリストアイテムの次にくる要素を取得したい場合に.nextElementSiblingを使用することができます。

// HTMLのリストアイテムを示す要素を取得
var currentItem = document.getElementById('current-item');

// currentItemの次の兄弟要素を取得
var nextItem = currentItem.nextElementSibling;

// 次の要素があれば、何かの操作を行う
if (nextItem) {
  // 例:次の要素のテキスト内容をコンソールに出力
  console.log(nextItem.textContent);
}

実際のユースケースとしては、例えばウェブページにおいてユーザーが現在選択しているメニューアイテムをハイライトし、その次のメニューアイテムにも何らかのスタイルを適用したいときなどに役立ちます。

DOMの探索を容易にし、ユーザーインターフェイスの動的な変更を効率的に行うためによく用いられるプロパティです。

アコーディオンの開閉と画像切り替えのサンプル

早速、サンプルです。

Q&Aのアコーディオンをそれぞれクリックすると、アコーディオン下に置いてある画像がそれぞれ設定した画像に切り替わります。

Question one

あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。

Question two

Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューター

Question three

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut

Question four

ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキス

かかかず
かかかず

切り替わる時、ローディング中のスピナーを表示してから切り替えます。

実装の手順と方法

手順と方法

コードの詳細の前に、実装の手順と方法について解説していきます。

HTMLを記述

まずは、HTMLを記述します。

設置したい場所に記述しましょう。

<div class="acco">
  <div class="accordion">Question one </div>
  <div class="panel">
  <p>あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。</p>
  </div>
  <div class="accordion">Question two </div>
  <div class="panel">
    <p>Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューター</p>
  </div>
  <div class="accordion">Question three </div>
  <div class="panel">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut </p>
  </div>
  <div class="accordion">Question four </div>
  <div class="panel">
    <p>ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキス</p>
  </div>
</div>

<div id="imageContainer"><img src="https://source.unsplash.com/640x360/?dog"></div>
JavaScriptを記述

次に、JavaScriptのコードを記述します。

コードは <body>〜</body>で、</body> の閉じタグ(クロージングタグ)の前に記述しましょう。

document.addEventListener('DOMContentLoaded', function() {
  var acc = document.getElementsByClassName('accordion');

  function switchImage(accordionIndex) {
    var imageContainer = document.getElementById('imageContainer');
    imageContainer.innerHTML = '<div class="loader"></div>'; // スピナーを表示

    var imageUrls = [
      'https://source.unsplash.com/640x360/?nature',
      'https://source.unsplash.com/640x360/?city',
      'https://source.unsplash.com/640x360/?technology',
      'https://source.unsplash.com/640x360/?space'
    ];

    var img = new Image();
    img.onload = function() {
      imageContainer.innerHTML = ''; // スピナーをクリア
      imageContainer.appendChild(img); // 画像を表示
    };
    img.onerror = function() {
      imageContainer.innerHTML = '画像を読み込めませんでした。'; // エラーメッセージを表示
    };
    img.src = imageUrls[accordionIndex]; // 画像のURLを設定
  }

  Array.from(acc).forEach(function(element, index) {
    element.addEventListener('click', function() {
      // 他のアコーディオンの 'active' クラスを削除し、パネルを閉じる
      Array.from(acc).forEach(function(el) {
        if (el !== element) {
          el.classList.remove('active');
          el.nextElementSibling.style.maxHeight = null;
        }
      });

      // クリックされたアコーディオンの 'active' クラスをトグル
      var isActive = element.classList.toggle('active');
      var panel = this.nextElementSibling;
      if (isActive) {
        panel.style.maxHeight = panel.scrollHeight + "px";
      } else {
        panel.style.maxHeight = null;
      }

      // アコーディオンに応じた画像を切り替え
      switchImage(index);
    });
  });
});

CSSを記述

最後にCSSを書いて、見た目を整えましょう。

.accordion {
    display: block;
    line-height: 50px;
    border: none;
    cursor: pointer;
    font-size: 1.2rem;
    transition: 0.5s ease-in;
    position: relative;
    padding-left: 60px;
    height: 53px;
    margin: 0;
    border-radius: 5px;
    background: #FFF;
    margin-bottom: 15px;
    font-weight: 600;
}
.accordion:before {
    content: "Q";
    position: absolute;
    left: 15px;
    top: 50%;
    display: inline-block;
    width: 35px;
    height: 35px;
    line-height: 35px;
    vertical-align: middle;
    text-align: center;
    font-family: Arial, sans-serif;
    font-size: 21px;
    background: #313131;
    color: #fff;
    border-radius: 50%;
    transform: translateY(-50%);
}
.accordion.active {
    margin-bottom: 0;
}
div.panel{
  max-height:0;
  overflow:hidden;
  transition: 0.3s ease-out;
}
.panel p {
    padding: 10px 20px;
    background: #fafafa;
    margin: 0 0 15px;
    position:relative;
    padding-left: 60px;
}
.panel p:before {
    content: "A";
    position: absolute;
    left: 15px;
    display: inline-block;
    width: 35px;
    height: 35px;
    line-height: 35px;
    vertical-align: middle;
    text-align: center;
    font-size: 21px;
    background: #e80000;
    color: #fff;
    border-radius: 50%;
}
.acco{
  position:relative;
}
div.accordion:hover{
  background-color: #ddd;
}
div.accordion:after {
    content: '\02795';
    font-size: 1rem;
    color: #777;
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-46%);
}
div.accordion.active:after {
    content: "\2796";
}
div#imageContainer {
    position: relative;
    background: #f9f9f9;
    width: 100%;
    min-height: 340px;
}
#imageContainer img {
    width: 100%;
    height: 360px;
    object-fit: cover;
}

.loader {
  border: 6px solid #f3f3f3;
  border-radius: 50%;
  border-top: 6px solid #3498db;
  width: 40px;
  height: 40px;
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

ざっくりとしたコードの解説

コードは、HTML・JavaScript・CSSの3種類です。ざっくりですが、順に解説していきます。

HTML

HTMLではアコーディオン機能と画像表示エリアを含む要素で構成されています。

<div class="acco">
  <div class="accordion">Question one </div>
  <div class="panel">
  <p>あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。</p>
  </div>
  <div class="accordion">Question two </div>
  <div class="panel">
    <p>Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューターの世界が広がります。1234567890Windowsでコンピューター</p>
  </div>
  <div class="accordion">Question three </div>
  <div class="panel">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut </p>
  </div>
  <div class="accordion">Question four </div>
  <div class="panel">
    <p>ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキスト。ダミーテキス</p>
  </div>
</div>

<div id="imageContainer"><img src="https://source.unsplash.com/640x360/?dog"></div>

アコーディオンはクリックで開閉する情報セクションで、ここには4つの異なるセクション(質問)があります。各セクションの下には詳細なテキストが隠されており、クリックによって表示されます。

  • 「div.acco」は全てのアコーディオンセクションを包含するコンテナです。
  • 「div.accordion」は各アコーディオンのタイトルを表し、これをクリックすると対応する「div.panel」が開閉します。
  • 「div.panel」には各セクションの内容が含まれます。
  • 「div#imageContainer」は、アコーディオンの操作に応じて変更可能な画像を表示するためのエリアです。デフォルトで、犬の画像が表示されています(Unsplashからのランダムな画像)。JavaScriptを使って、アコーディオンのセクションがクリックされるたびにこの画像を変更することが想定されています。

JavaScript

JavaScriptは、アコーディオン機能と画像の動的切り替え機能。

アコーディオンのセクションをクリックすると、そのセクションが展開し、他のセクションが閉じます。

また、クリックされたセクションに応じて、指定されたURLから画像を読み込み、表示します。画像が読み込まれるまでローディングスピナーが表示され、画像の読み込みが完了するとスピナーが画像に置き換わります。

// DOMが完全に読み込まれた後に実行される関数を設定
document.addEventListener('DOMContentLoaded', function() {
  // 'accordion'クラスを持つすべての要素を取得
  var acc = document.getElementsByClassName('accordion');

  // 指定されたインデックスに応じた画像に切り替える関数
  function switchImage(accordionIndex) {
    var imageContainer = document.getElementById('imageContainer');
    imageContainer.innerHTML = '<div class="loader"></div>'; // ローディングスピナーを表示

    // 画像URLの配列
    var imageUrls = [
      'https://source.unsplash.com/640x360/?nature',
      'https://source.unsplash.com/640x360/?city',
      'https://source.unsplash.com/640x360/?technology',
      'https://source.unsplash.com/640x360/?space'
    ];

    // 新しい画像要素を作成
    var img = new Image();
    img.onload = function() {
      imageContainer.innerHTML = ''; // 画像が読み込まれたらスピナーをクリア
      imageContainer.appendChild(img); // 画像を表示
    };
    img.onerror = function() {
      imageContainer.innerHTML = '画像を読み込めませんでした。'; // 画像の読み込みに失敗した場合のメッセージを表示
    };
    img.src = imageUrls[accordionIndex]; // 画像のURLを設定
  }

  // 各アコーディオン要素にクリックイベントリスナーを設定
  Array.from(acc).forEach(function(element, index) {
    element.addEventListener('click', function() {
      // 他のアコーディオンから 'active' クラスを削除し、そのパネルを閉じる
      Array.from(acc).forEach(function(el) {
        if (el !== element) {
          el.classList.remove('active');
          el.nextElementSibling.style.maxHeight = null;
        }
      });

      // クリックされたアコーディオンの 'active' クラスをトグルし、対応するパネルを開閉
      var isActive = element.classList.toggle('active');
      var panel = this.nextElementSibling;
      if (isActive) {
        panel.style.maxHeight = panel.scrollHeight + "px"; // パネルを開く
      } else {
        panel.style.maxHeight = null; // パネルを閉じる
      }

      // アコーディオンに応じた画像を切り替える
      switchImage(index);
    });
  });
});
かかかず
かかかず

各コードの詳細はコメントアウトの中の解説を参考にしてみてください。

CSS

CSSでは、アコーディオンUIと画像表示エリアにスタイルを適用しています。

.accordion {
    display: block;
    line-height: 50px;
    border: none;
    cursor: pointer;
    font-size: 1.2rem;
    transition: 0.5s ease-in;
    position: relative;
    padding-left: 60px;
    height: 53px;
    margin: 0;
    border-radius: 5px;
    background: #FFF;
    margin-bottom: 15px;
    font-weight: 600;
}
.accordion:before {
    content: "Q";
    position: absolute;
    left: 15px;
    top: 50%;
    display: inline-block;
    width: 35px;
    height: 35px;
    line-height: 35px;
    vertical-align: middle;
    text-align: center;
    font-family: Arial, sans-serif;
    font-size: 21px;
    background: #313131;
    color: #fff;
    border-radius: 50%;
    transform: translateY(-50%);
}
.accordion.active {
    margin-bottom: 0;
}
div.panel{
  max-height:0;
  overflow:hidden;
  transition: 0.3s ease-out;
}
.panel p {
    padding: 10px 20px;
    background: #fafafa;
    margin: 0 0 15px;
    position:relative;
    padding-left: 60px;
}
.panel p:before {
    content: "A";
    position: absolute;
    left: 15px;
    display: inline-block;
    width: 35px;
    height: 35px;
    line-height: 35px;
    vertical-align: middle;
    text-align: center;
    font-size: 21px;
    background: #e80000;
    color: #fff;
    border-radius: 50%;
}
.acco{
  position:relative;
}
div.accordion:hover{
  background-color: #ddd;
}
div.accordion:after {
    content: '\02795';
    font-size: 1rem;
    color: #777;
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-46%);
}
div.accordion.active:after {
    content: "\2796";
}
div#imageContainer {
    position: relative;
    background: #f9f9f9;
    width: 100%;
    min-height: 340px;
}
#imageContainer img {
    width: 100%;
    height: 360px;
    object-fit: cover;
}

.loader {
  border: 6px solid #f3f3f3;
  border-radius: 50%;
  border-top: 6px solid #3498db;
  width: 40px;
  height: 40px;
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
  • 「.accordion」クラスはアコーディオンの見出しに適用され、見た目とホバー時の背景色変更などの基本スタイルを定義します。
  • 「.accordion:before」は、各アコーディオンの見出しの前に”Q”(質問の意味)を示す円形のアイコンを追加します。
  • 「.accordion.active」と「.accordion.active:after」の擬似要素は、アコーディオンが選択(アクティブ)状態のときのスタイルを定義し、アクティブ時には”−”アイコンを表示します。
  • 「div.panel」はアコーディオンのコンテンツパネルに適用され、デフォルトでは非表示(max-height: 0)に設定されていますが、アクティブ時にはコンテンツが展開されるようになっています。
  • 「.panel p」と「.panel p:before」はパネル内のテキストと、その前に”A”(答えの意味)を示す円形のアイコンにスタイルを適用します。
  • 「#imageContainer」と「#imageContainer img」は、画像を表示するコンテナとその中のimgタグにスタイルを適用します。画像はコンテナの幅に合わせて調整され、高さが固定されています。
  • 「.loader」クラスと関連するキーフレームアニメーションは、画像が読み込まれるまでの間に表示されるローディングスピナーにスタイルを提供します。

さいごに

さいごに

今回は、JavaScriptの.nextElementSiblingを活用して、アコーディオンの開閉機能と画像の切り替えについてでした。

実装例を参考に、JavaScriptを用いたさまざまな機能の実装にチャレンジしてみてください。

UI

  • 他のウィンドウが開くことができないポップアップのUIです。

    モーダル

    モーダル

  • 並列な関係を持つ情報を1つずつ格納するUIです。

    タブ

    タブ

  • サイドから全体を覆うほど大きいメニュー表示するUIです。

    ドロワー

    ドロワー

  • 画像などのコンテンツをスライド表示させるUIです。

    スライダー

    スライダー

  • スクロールで表示が変化するスニペットです。

    スクロール

    スクロール

  • クリックすると隠れていた部分が開閉するUIです。

    アコーディオン

    アコーディオン

  • ページのhタグを取得して目次を生成するスニペットです。

    目次

    目次

  • ページの読み込み時にアニメーションをするスニペットです。

    ローディングアニメーション

    ローディングアニメーション

  • マウスオーバーした際に表示される補足説明です。

    ツールチップ

    ツールチップ

  • ページ内上部にあるナビゲーションUIです。

    ヘッダー

    ヘッダー

  • 行と列の組み合わせでできているUIです。

    テーブル

    テーブル

  • データを表やグラフで可視化して見せるUIです。

    グラフ

    グラフ

  • 背景をアニメーションで動かすスニペットです。

    背景

    背景

  • 短いテキスト情報をスクロール表示するUIです。

    ニュースティッカー

    ニュースティッカー

フォーム

  • ラジオボタン、チェックボックス、ドロップダウンリストなどを通じて、ユーザーが入力できるUIです。

    フォーム

    フォーム

文字

  • 文字列をJavaScriptで装飾・動きをつけるスニペットです。

    文字の装飾

    文字の装飾

  • 文字列の操作をして、置換・変更を行うスニペットです。

    文字の操作

    文字の操作

  • 文字列をカウントして表示などを行うスニペットです。

    文字のカウント

    文字のカウント

  • 数字の要素を取得して、変更するスニペットです。

    数字の操作

    数字の操作

ウィンドウ

classの操作

  • 要素を取得して、classを追加・削除するスニペットです。

    classの操作

    classの操作

要素の操作

API

  • WordPressのAPIを取得して表示するスニペットです。

    WP REST API

    WP REST API

  • Google Books APIsで書籍の情報を表示するスニペットです。

    Google Books APIs

    Google Books APIs

  • 楽天市場のAPIを取得して表示するスニペットです。

    楽天市場API

    楽天市場API

  • openBDのAPIを取得して表示するスニペットです。

    openBD

    openBD

画像・動画

  • 画像を取得して、アニメーションなどの変化を加えるスニペットです。

    画像の操作

    画像の操作

  • YouTubeの動画を表示するスニペットです。

    YouTube

    YouTube

リンク

  • ページ内のリンクを取得して変更・操作するスニペットです。

    リンク

    リンク

  • Google Analyticsとの連携をするスニペットです。

    Google Analytics

    Google Analytics

cookie

  • ブラウザのcookieを利用するスニペットです。

    cookie

    cookie

検索

  • 指定した要素の中から検索を行うスニペットです。

    検索

    検索