画像切り替え機能の制作例

画像切り替え slider スライダー

主な用途として新着情報の切り替えなどです。画像クリックで該当記事へ遷移する想定です。

現時点のコードは以下の通り: 他の制作物からの転用ですので変数名は仮です。
/**
 * 画像切り替え
 *
 * @author ao-system, Inc.
 * @date 2025-03-14
 */


(() => {
	'use strict';
	class Slider {
		#stageElement		= document.querySelector('section.diarythumb > div > div.stage');
		#stageBackElement	= document.querySelector('section.diarythumb > div > div.stage > div.back');
		#stageForeElement	= document.querySelector('section.diarythumb > div > div.stage > div.fore');
		#stageImages		= [
			document.querySelector('section.diarythumb > div > div.stage > div.fore > img:nth-of-type(1)'),
			document.querySelector('section.diarythumb > div > div.stage > div.fore > img:nth-of-type(2)'),
			document.querySelector('section.diarythumb > div > div.stage > div.fore > img:nth-of-type(3)'),
		];
		#figcaption			= document.querySelector('section.diarythumb > div > figcaption');
		#prevElement		= document.querySelector('section.diarythumb > div > div.more > figure:nth-of-type(1) > img');
		#nextElement		= document.querySelector('section.diarythumb > div > div.more > figure:nth-of-type(2) > img');
		//constant
		#emptyImage			= './image/blank.svg';
		//variable
		#objDiaries			= [];
		//
		constructor(obj) {
			this.#objDiaries = obj;
			this.#init();
		}
		#init() {
			this.#initThumbs();
			this.#setListener();
		}
		#setListener() {
			this.#prevElement.addEventListener('click',() => { this.#prev(); });
			this.#nextElement.addEventListener('click',() => { this.#next(); });
		}
		#prev() {
			const diaryId = this.#stageImages[2].getAttribute('data-diaryid');
			let index = -1;
			if (diaryId == 0) {
				index = this.#objDiaries.length - 1;
			} else if (this.#stageImages[0].getAttribute('data-diaryid') != 0) {
				const diaryId = this.#stageImages[1].getAttribute('data-diaryid');
				for (let i = 0; i < this.#objDiaries.length; i++) {
					if (this.#objDiaries[i].id == diaryId) {
						index = i;
						break;
					}
				}
			}
			if (index != -1) {
				this.#stageBackElement.innerHTML = this.#stageForeElement.innerHTML;
				[0,1,2].forEach((i) => {
					if (this.#objDiaries[index - i]) {
						this.#stageImages[2 - i].src = (this.#objDiaries[index - i].isThumbnail) ? `${this.#objDiaries[index - i].image}` : this.#emptyImage;
						this.#stageImages[2 - i].setAttribute('data-diaryid', this.#objDiaries[index - i].id);
					} else {
						this.#stageImages[2 - i].src = this.#emptyImage;
						this.#stageImages[2 - i].setAttribute('data-diaryid',0);
					}
				});
				const w = this.#stageImages[2].getBoundingClientRect().width + 10;
				this.#stageBackElement.animate(
					[
						{opacity: 1, transform: 'translateX(0px)'},
						{opacity: 0, transform: `translateX(${w}px)`},
					],
					{delay:0,duration:300,fill:'forwards',easing:'ease-out'}
				);
				this.#stageForeElement.animate(
					[
						{transform: `translateX(-${w}px)`},
						{transform: 'translateX(0px)'},
					],
					{delay:0,duration:300,fill:'forwards',easing:'ease-out'}
				);
				this.#figcaption.innerHTML = `${this.#objDiaries[index - 1].subject1}<br>${this.#objDiaries[index - 1].subject2}`;
				this.#figcaption.animate(
					[
						{opacity: 0, transform: 'translateX(-50px)'},
						{opacity: 1, transform: 'translateX(0px)'},
					],
					{delay:0,duration:300,fill:'forwards',easing:'ease-out'}
				);
			}
		}
		#next() {
			const diaryId2 = this.#stageImages[2].getAttribute('data-diaryid');
			if (diaryId2 == null) {
				return;	//記事が1個しかない場合
			}
			const diaryId0 = this.#stageImages[0].getAttribute('data-diaryid');
			let index = -1;
			if (diaryId0 == 0) {
				index = 0;
			} else if (this.#stageImages[2].getAttribute('data-diaryid') != 0) {
				const diaryId = this.#stageImages[1].getAttribute('data-diaryid');
				for (let i = 0; i < this.#objDiaries.length; i++) {
					if (this.#objDiaries[i].id == diaryId) {
						index = i;
						break;
					}
				}
			}
			if (index != -1) {
				this.#stageBackElement.innerHTML = this.#stageForeElement.innerHTML;
				[0,1,2].forEach((i) => {
					if (this.#objDiaries[index + i]) {
						this.#stageImages[i].src = (this.#objDiaries[index + i].isThumbnail) ? `${this.#objDiaries[index + i].image}` : this.#emptyImage;
						this.#stageImages[i].setAttribute('data-diaryid', this.#objDiaries[index + i].id);
					} else {
						this.#stageImages[i].src = this.#emptyImage;
						this.#stageImages[i].setAttribute('data-diaryid',0);
					}
				});
				const w = this.#stageImages[2].getBoundingClientRect().width + 10;
				this.#stageBackElement.animate(
					[
						{opacity: 1, transform: 'translateX(0px)'},
						{opacity: 0, transform: `translateX(-${w}px)`},
					],
					{delay:0,duration:300,fill:'forwards',easing:'ease-out'}
				);
				this.#stageForeElement.animate(
					[
						{transform: `translateX(${w}px)`},
						{transform: 'translateX(0px)'},
					],
					{delay:0,duration:300,fill:'forwards',easing:'ease-out'}
				);
				this.#figcaption.innerHTML = `${this.#objDiaries[index + 1].subject1}<br>${this.#objDiaries[index + 1].subject2}`;
				this.#figcaption.animate(
					[
						{opacity: 0, transform: 'translateX(50px)'},
						{opacity: 1, transform: 'translateX(0px)'},
					],
					{delay:0,duration:300,fill:'forwards',easing:'ease-out'}
				);
			}
		}
		#initThumbs() {
			this.#stageImages[0].src = this.#emptyImage;
			this.#stageImages[0].setAttribute('data-diaryid', 0);
			this.#figcaption.innerHTML = `${this.#objDiaries[0].subject1}<br>${this.#objDiaries[0].subject2}`;
			for (let i = 0; i < 2; i++) {
				if (this.#objDiaries[i]) {
					this.#stageImages[i + 1].src = (this.#objDiaries[i].isThumbnail) ? `${this.#objDiaries[i].image}` : this.#emptyImage;
					this.#stageImages[i + 1].setAttribute('data-diaryid', this.#objDiaries[i].id);
				} else {
					this.#stageImages[i + 1].src = this.#emptyImage;	//記事が1個しかない場合の[2]
				}
			}
			for (let i = 0; i < 3; i++) {
				this.#stageImages[i].addEventListener('click',() => {
					const diaryId = this.#stageImages[i].getAttribute('data-diaryid');
					if (diaryId > 0) {
						//window.location.href = `./diary/?id=${diaryId}`;
					}
				});
			}
		}
	}

	new Slider([
		{
			id: 1,
			image: './image/panel01.webp',
			subject1: 'テキスト1',
			subject2: 'テキスト1が更新されました。',
			isThumbnail: true
		},
		{
			id: 2,
			image: './image/panel02.webp',
			subject1: 'テキスト2',
			subject2: '何らかの情報',
			isThumbnail: true
		},
		{
			id: 3,
			image: './image/panel03.webp',
			subject1: 'ダミーテキスト',
			subject2: 'お知らせのテキストなど。',
			isThumbnail: true
		},
		{
			id: 4,
			image: './image/panel04.webp',
			subject1: 'お知らせ',
			subject2: '何らかの情報を表示する',
			isThumbnail: true
		},
		{
			id: 5,
			image: './image/panel05.webp',
			subject1: 'テキスト5',
			subject2: 'テキスト5が更新されました。',
			isThumbnail: true
		},
		{
			id: 6,
			image: './image/panel06.webp',
			subject1: 'テキスト6',
			subject2: 'テキスト6が更新されました。',
			isThumbnail: true
		},
	]);
})();
2025年3月初版
このサイトについてのお問い合わせはエーオーシステムまでお願いいたします。
ご使用上の過失の有無を問わず、本プログラムの運用において発生した損害に対するいかなる請求があったとしても、その責任を負うものではありません。