Skip to content

マウスhoverで画像が切り替わるスライド [jQuery不要]

テキストにマウスhoverすると、画像が切り替わるスライドの作り方です。
完成形はこちらです。

実現したいこと

  • テキストにマウスhoverすると画像が切り替わる

1. htmlを用意する

切り替わる画像エリア slide-image と、マウスhoverするテキストエリア slide-text の2つを用意します。

<div class="slide-wrap">
  <ul class="slide-image">
    <li class="slide-image__item">
      <img src="https://source.unsplash.com/rkaahInFlBg/640x360" alt="" />
    </li>
    <li class="slide-image__item">
      <img src="https://source.unsplash.com/3esjG-nlgyk/640x360" alt="" />
    </li>
    <li class="slide-image__item">
      <img src="https://source.unsplash.com/9HnSQn4TVEg/640x360" alt="" />
    </li>
  </ul>
  <div class="slide-text">
    <p class="slide-text__text">
      <span>Iron Man</span>
    </p>
    <p class="slide-text__text">
      <span>Thor</span>
    </p>
    <p class="slide-text__text">
      <span>Captain America</span>
    </p>
  </div>
</div>

2. cssでスタイルを設定する

画像エリアはマウスhoverで切り替わるようにするため、1枚だけ見える状態にします。
1で作成したhtmlの1つ目の画像に current というclassを追加します。

<li class="slide-image__item current">
  <img src="https://source.unsplash.com/rkaahInFlBg/640x360" alt="" />
</li>

画像群は display: grid; で重なるようにします。

後ほどJavaScriptでマウスhoverと連動して current の付け替えをしますが、 その際に current の場合に opacity: 1; および visibility: visible; 、 そうでないときは opacity: 0; および visibility: hidden; になるように設定します。 transition で切り替わるときの状態の変化も設定します。

.slide-image {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  overflow: hidden;

  &__item {
    grid-column: 1 / -1;
    grid-row: 1 / -1;
    opacity: 0;
    visibility: hidden;
    transition:
      opacity 0.45s cubic-bezier(0.65, 0, 0.35, 1),
      visibility 0.45s cubic-bezier(0.65, 0, 0.35, 1);

    &.current {
      opacity: 1;
      visibility: visible;
      transition:
        opacity 0.45s cubic-bezier(0.65, 0, 0.35, 1),
        visibility 0.45s cubic-bezier(0.65, 0, 0.35, 1);
    }
  }
}

3. JavaScriptでclassの付け替えをする

テキストにマウスhoverした場合にどの画像を current にするか、
カスタムデータ属性の data-*id を使用して対応するようにします。

また、JavaScriptから操作する時のために、
画像に js-target テキストに js-trigger とそれぞれclassを追加します。

<div class="slide-wrap">
  <ul class="slide-image">
    <li id="item-01" class="slide-image__item js-target current">
      <img src="https://source.unsplash.com/rkaahInFlBg/640x360" alt="" />
    </li>
    <li id="item-02" class="slide-image__item js-target">
      <img src="https://source.unsplash.com/3esjG-nlgyk/640x360" alt="" />
    </li>
    <li id="item-03" class="slide-image__item js-target">
      <img src="https://source.unsplash.com/9HnSQn4TVEg/640x360" alt="" />
    </li>
  </ul>
  <div class="slide-text">
    <p data-target="item-01" class="slide-text__text js-trigger">
      <span>Iron Man</span>
    </p>
    <p data-target="item-02" class="slide-text__text js-trigger">
      <span>Thor</span>
    </p>
    <p data-target="item-03" class="slide-text__text js-trigger">
      <span>Captain America</span>
    </p>
  </div>
</div>

JavaScriptではまず画像群とテキスト群を変数として宣言します。

const triggers = document.querySelectorAll(".js-trigger");
const images = document.querySelectorAll(".js-target");

テキストそれぞれにマウスhoverする度に処理を実行したいので、
triggers に対して forEach を使用します。

カーソルが要素の上を移動したときにイベントが発生する mouseover を使用して、
マウスhoverした際に処理が実行されるようにします。

triggers.forEach(trigger => {
  trigger.addEventListener('mouseover', (e) => {
    // ここに処理を記述
  });
}

ここからは画像の切り替えに必要な current classの付け替え処理についてです。

マウスhoverされているテキストを取得して item に格納します。
そのテキストに対応する画像idを取得して target に格納します。 取得したidをもとに表示させたい画像を取得して current に格納します。

const item = e.currentTarget;
const target = item.getAttribute("data-target");
const current = document.getElementById(target);

現在 current になっている画像を非アクティブにするために 一旦、画像群に付与されている current classを削除します。

images.forEach((image) => {
  image.classList.remove("current");
});

最後に先ほど取得した current に class current を追加します。

current.classList.add("current");

最終的なJavaScriptのソースコードです。

const triggers = document.querySelectorAll('.js-trigger');
const images = document.querySelectorAll('.js-target');

triggers.forEach(trigger => {
  trigger.addEventListener('mouseover', (e) => {
    const item = e.currentTarget;
    const target = item.getAttribute('data-target');
    const current = document.getElementById(target);
    images.forEach(image => {
      image.classList.remove('current');
    });
    current.classList.add('current');
  });
});

デモ

テキストにマウスhoverすると画像が切り替わります。

デモ(CodeSandbox)

Reference 参照