メイン画像とサムネイルを連動させて画像を切り替える
こんにちは、トシキです。
今回は、メイン画像とサムネイルを連動させて、画像を切り替える方法について解説します。
本記事の内容
スポンサードサーチ
【1】メイン画像とサムネイルを連動させて画像を切り替える
メイン画像が上に1枚で、その下にサムネイルが4枚並んでいるレイアウトになります。
See the Pen メイン画像とサムネイルを連動させて画像を切り替える by tosshii (@totototosshii) on CodePen.
1-1. HTML
<div class="bl_imgSwitcher" id="js_imgSwitcher">
<div class="bl_imgSwitcher_main">
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju7U8esONERDN_s7GbaKtQbHoaZ9ogxlzbcSf9I8_JbyCrXUM9BvvFFg-1LwbMZHM2x-5pBYWxlhTSqPa_9eLwZeWY2ZzHhVg_iQqb0PRsSxP-WxElIjlm1BT1jy0fCRtHAckDbyCjdd-u/s1600/no_image_logo.png" alt="No Image">
</div>
<div class="bl_imgSwitcher_thumb">
<button class="bl_imgSwitcher_btn" type="button"><img src="https://picsum.photos/id/229/1000/800" alt="ダミー01"></button>
<button class="bl_imgSwitcher_btn" type="button"><img src="https://picsum.photos/id/230/800/1000" alt="ダミー02"></button>
<button class="bl_imgSwitcher_btn" type="button"><img src="https://picsum.photos/id/231/1200/800" alt="ダミー03"></button>
<button class="bl_imgSwitcher_btn" type="button"><img src="https://picsum.photos/id/232/800/1200" alt="ダミー04"></button>
</div>
</div>
メイン画像<div class="bl_imgSwitcher_main">
の直下には、ダミーのimg
を用意します(画像はいらすとやから借りました)。src
が空だとHTML構文エラーになるので、ダミー用のsrc
は用意してください。
各サムネイルのimg
は、<button class="bl_imgSwitcher_btn" type="button">
で囲んでいます(画像はLorem Picsumから借りました)。
1-2. CSS
/* SCSS */
body{
margin-top: 20px;
}
// ラッパー
.bl_imgSwitcher {
max-width: 900px;
margin-inline: auto;
}
// メイン画像のエリア
.bl_imgSwitcher_main {
aspect-ratio: 3/2;
border-radius: 20px;
overflow: hidden;
img {
width: 100%;
object-fit: cover;
}
}
// サムネイル画像のエリア
.bl_imgSwitcher_thumb {
display: flex;
gap: 0 4%;
margin-top: 4%;
}
// サムネイル画像の各ボタン
.bl_imgSwitcher_btn {
width: 22%;
overflow: hidden;
border-radius: 20px;
position: relative;
&::before {
content: "";
border-radius: inherit;
position: absolute;
inset: 0;
z-index: 10;
transition: background-color .4s;
}
@media (any-hover: hover) {
&:hover::before {
background-color: rgb(255 255 255/.5);
}
}
&:focus-visible::before {
background-color: rgb(255 255 255/.5);
}
img {
width: 100%;
aspect-ratio: 1;
object-fit: cover;
}
}
// .is_activeクラスが付与されたら、サムネイル画像に半透明の白背景を適用
.bl_imgSwitcher_btn.is_active::before {
background-color: rgb(255 255 255/.5);
}
現在選択されているサムネイル<button class="bl_imgSwitcher_btn" type="button">
に.is_active
クラスを付与して、擬似要素before
に半透明の白背景を適用します。
また、ホバーとフォーカス時にも同様のスタイルを指定しています。
1-3. JavaScript
window.addEventListener('DOMContentLoaded', () => {
const imgSwitcher = document.getElementById('js_imgSwitcher');
if (imgSwitcher) {
const mainImg = document.querySelector('.bl_imgSwitcher_main img');
const thumbBtns = document.querySelectorAll('.bl_imgSwitcher_btn');
// 1番目のサムネイル画像をメイン画像に適用し、.is_activeクラスを付与
mainImg.src = thumbBtns[0].querySelector('img').src;
mainImg.alt = thumbBtns[0].querySelector('img').alt;
thumbBtns[0].classList.add('is_active');
// サムネイル画像がフォーカスされたときの処理
thumbBtns.forEach(thumbBtn => {
thumbBtn.addEventListener('focus', switchImage);
});
function switchImage() {
const img = this.querySelector('img');
mainImg.style.transition = 'opacity .3s ease-out';
mainImg.style.opacity = 0;
setTimeout(() => {
mainImg.src = img.src;
mainImg.alt = img.alt;
mainImg.style.opacity = 1;
}, 300);
thumbBtns.forEach(thumbBtn => thumbBtn.classList.remove('is_active'));
this.classList.add('is_active');
}
}
});
const imgSwitcher = document.getElementById('js_imgSwitcher');
if (imgSwitcher)
id="js_imgSwitcher"
を取得して、その要素が存在しないページではコンソールエラーが出ないように条件分岐しています。
const mainImg = document.querySelector('.bl_imgSwitcher_main img');
const thumbBtns = document.querySelectorAll('.bl_imgSwitcher_btn');
// 1番目のサムネイル画像をメイン画像に適用し、.is_activeクラスを付与
mainImg.src = thumbBtns[0].querySelector('img').src;
mainImg.alt = thumbBtns[0].querySelector('img').alt;
thumbBtns[0].classList.add('is_active');
メイン画像のimg
と、全てのサムネイルのbutton
要素を取得して変数へ代入します。
その後、取得した1番目thumbBtns[0]
のサムネイル情報(src
とalt
)を、メイン画像のimg
に代入しています。
最後に1番目のサムネイルに.is_active
クラスを付与して、半透明の白背景を適用しています。
ここまでがページにアクセスした時の初期状態になります。
// サムネイル画像がフォーカスされたときの処理
thumbBtns.forEach(thumbBtn => {
thumbBtn.addEventListener('focus', switchImage);
});
任意のサムネイルthumbBtn
がフォーカス(クリックやTabキー移動)されたら、後に解説するswitchImage
関数を実行します。
function switchImage() {
const img = this.querySelector('img');
mainImg.style.transition = 'opacity .3s ease-out';
mainImg.style.opacity = 0;
setTimeout(() => {
mainImg.src = img.src;
mainImg.alt = img.alt;
mainImg.style.opacity = 1;
}, 300);
thumbBtns.forEach(thumbBtn => thumbBtn.classList.remove('is_active'));
this.classList.add('is_active');
}
始めに先ほどのthumbBtn.addEventListener('focus', switchImage);
でフォーカスされた、サムネイルのimg
要素を取得して定数img
に代入します。
次にメイン画像mainImg
にtransition
とopacity
のスタイルを指定して、opacity
は透明にします。
setTimeout
で0.3秒後に以下の処理を実行しています。
- 定数
img
に代入したサムネイル情報(src
とalt
)をメイン画像のimg
に代入 opacity
で透明にしたメイン画像を表示
前もってmainImg.style.transition = 'opacity .3s ease-out';
を指定しているため、opacity
はフワッと表示されます。
thumbBtns.forEach(thumbBtn => thumbBtn.classList.remove('is_active'));
this.classList.add('is_active');
.is_active
クラスを全てのサムネイルからを外したのち、フォーカスされたサムネイルにのみ付与してます。
【2】まとめ
今回はサムネイルの情報をメイン画像に適用して表示させるシンプルな動作でしたが、もし前後矢印やドット(いわゆるスライダー要素)が必要になると複雑化するので、その場合はSplideなどのスライダーライブラリを採用するのが良いと思います。
以上になります。
人気記事Webサイトにフォントサイズ変更ボタンを実装する方法(jQuery使用)
人気記事【脱jQuery】スクロールしたら画面上部に追従メニューを表示する方法