サムネイル画像をクリックしてふわっと画像を切り替える方法

すぱっと切り替える場合

src属性を切り替えるだけなので、特に問題なく動作すると思います。
後述する、ふわっと切り替える場合の比較対象としてください。

CODEPEN

「Run Pen」をクリックしてください。

See the Pen change slide image by blue moon (@blue-moon) on CodePen.

HTMLファイル

<div id="main-img">
  <!-- デフォルトの画像、サムネイルクリックでこのimgタグの属性を切り替え  -->
  <img src="your path 1" alt="image-1">
</div>

<p>下のサムネイル画像をクリックすると、<br>上の大きな画像が切り替わります。</p>

<!-- サムネイルリスト -->
<ul class="slide-list">
  <li class="slide-item">
    <img src="your path 1" alt="image-1">
  </li>
  <li class="slide-item">
    <img src="your path 2" alt="image-2">
  </li>
  <li class="slide-item">
    <img src="your path 3" alt="image-3">
  </li>
  <li class="slide-item">
    <img src="your path 4" alt="image-">
  </li>
</ul>

CSSファイル

いたって普通で、画像をふわっと切り替えるための工夫はありませんが、参考までに。

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

img {
  width: 100%;
  height: 100%;
  object-fit: cover; /* アスペクト比を維持したまま全体を埋める */
  object-position: center; /* 親要素の中央に配置 */
  transition: transform 0.5s ease-in-out; /* マウスオーバーで拡大する時の時間とイージング */
  cursor: pointer;
}

img:hover {
  transform: scale(1.2); /* マウスオーバーで拡大 */
}

/* メイン画像の外枠 */
#main-img {
  margin: 20px auto;
  width: 300px;
  height: 168px;
  overflow: hidden; /* マウスオーバーで拡大した時にはみ出さない */
}

/* メイン画像 */
#main-img img {
  filter: brightness(1.1); /* 画像が暗かったため明るく */
}

/* サムネイルのリスト */
.slide-list {
  margin: 20px auto;
  width: 300px;
  height: 220px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

/* サムネイル画像 */
.slide-item {
  width: 48.5%;
  height: 100px;
  overflow: hidden; /* マウスオーバーで拡大した時にはみ出さない */
}

p {
  margin: 10px auto;
  width: fit-content;
}

画像が暗かったため、filterプロパティで簡易的に明るくしています。
backdrop-filterというプロパティもあります。

JSファイル

$(".slide-item").click(function () { //サムネイル画像をクリックしたら
  const mainImg = $("#main-img").children("img"); //メイン画像本体を指定
  const imgSrc = $(this).children("img").attr("src"); //サムネイルのsrc属性の値を取得
  mainImg.attr("src", imgSrc); //画像のsrc属性をメイン画像のimgタグにセット
});

ふわっと切り替える場合

ふわっとしたニュアンスで切り替えたいと思います。
ただ、これが単純なようではまることがあります。一瞬画像が見えてフェードインしたり、ふわっといかなかったり….

これをシンプルな方法で実装しています。

CODEPEN

「Run Pen」をクリックしてください。

See the Pen change slide image softly by blue moon (@blue-moon) on CodePen.

JSファイル

$(".slide-item").click(function () { //サムネイル画像をクリックしたら
  const mainImgArea = $("#main-img"); //メイン画像の外枠を指定
  const mainImg = $("#main-img").children("img"); //メイン画像本体を指定
  const imgSrc = $(this).children("img").attr("src"); //サムネイルのsrc属性の値を取得

  mainImgArea.fadeOut(400, function () { //画像の外枠をフェードアウト、時間400msはデフォルト、好みのms秒を指定
    mainImg.attr("src", imgSrc); //画像のsrc属性をメイン画像のimgタグにセット
    mainImgArea.fadeIn(400); //画像の外枠をフェードイン、時間400msはデフォルト、好みのms秒を指定
  });
});

srcの属性をセットする要素の親要素をフェードイン・フェードアウトしています。
属性がセットされた時点では、画像が入っている親要素がまだ完全に見えていないので(フェードインが始まる時)、画像がすぱっと切り替わらない、という理屈です。

もし、サイトの1ページ内にメイン画像とサムネイル画像のグループが複数存在するならば、メイン画像外枠のIDをクラスに変更し、変数部分を下記のように記述すれば動作します。

  const mainImgArea = $(this).parent(".slide-list").siblings(".main-img"); //メイン画像の外枠を指定
  const mainImg = $(this).parent(".slide-list").siblings(".main-img").children("img"); //メイン画像本体を指定

要素をidで特定できないため、メソッドチェーンが長くなっています。
これを紐解くと、変数mainImgAreaは、クリックした画像アイテムの親要素(ulタグ)の、兄弟要素にある、メイン画像の外枠を指定しています。

惜しい例

下記は、フェードインと画像切り替えを同じimgタグに実装している例です。
クリックすると、フェードイン前に画像が一瞬表示されることが確認できると思います。
敢えて切り替え時間(フェードイン時間)をかなり長めに2秒にしています。

CODEPEN

「Run Pen」をクリックしてください。

See the Pen change slide image failure by blue moon (@blue-moon) on CodePen.

JSファイル

$(".slide-item").click(function () { //サムネイル画像をクリックしたら
  const mainImg = $("#main-img").children("img"); //メイン画像本体を指定
  const imgSrc = $(this).children("img").attr("src"); //サムネイルのsrc属性の値を取得
  mainImg.fadeOut(2000).attr("src", imgSrc).fadeIn(2000); //画像のsrc属性をメイン画像のimgタグにセット
});

【参考】画像を中央寄せにする他の方法

画像の中央寄せは、object-fit: cover; と object-position: center;(初期値 50% 50%)で行っています(imgタグには、幅と高さを指定、height: auto;等では効かない)。

MDNの記事です。
object-fit
object-position

以下は、今回紹介した方法以外のメモです。

imgタグは使わず、画像は設置したい要素の背景画像とする方法(ここではクラス名を仮に「background」としています)。

.background {
  background-image: url("画像のパス");
  background-position: center;
}

imgタグを囲う親要素に、フレックスボックスレイアウトを使用する方法 (ここではクラス名を仮に「parent」としています)。

.parent {
  display: flex;
  justify-content: center; //水平方向中央
  align-items: center; //垂直方向中央
}

上から何%等の細かい位置指定がなく単に中央寄せにするだけなら、フレックスボックスレイアウトも便利です。

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