【JS】アローボタン付きスライダー

JavaScript
動点P
動点P

スライダーを付けたいけどjQueryとかに頼りたくない!

動点Qちゃん
動点Qちゃん

ではJavaScriptで動くスライダーを考えましょう・・・

というわけで勉強のためにスライダーを自作しようと思いいろいろなスライダーを見てみたのですが、下記のページのスライダーがとても参考になりましたので、この構造をベースにして作ってみました。

参考リンク【JavaScript】スライダーを自作 arrow編ーWEB制作・開発者の記録

See the Pen carousel-demo by inu (@tenp) on CodePen.

ほぼ構造はまんまですが、ホバーで拡大するのと、アローボタンを外に出してみたりとか変更しています。

あとIE対応のためforEach文をfor文に変更しています。基本的な構造は元の製作者の方が説明しているので、自分の勉強と健忘録のため難しかったところやコードを変更したところをメインに解説していきます。

スライダーの構造の全体

スライダーが動く仕組みですが、まず要素を何個見えている状態にするか決めます。今回は3個にしました。その3つはCSSのdisplayのプロパティで見える設定にする(クラスをつける)、それ以外は見えないよう設定しておきます。戻るボタンと次へボタンによって見える設定のクラスとつけたりとったりしながら動かしています。

要素に番号をつける

スライダーで流れてくる要素を操作したりどの位置のものか把握しておきたいので、全ての要素に番号を付けます。

まず要素を取得しておく。

const slider_list = document.querySelector(".slider_list");
const slider_items = document.querySelectorAll(".slider_item");
const next_button = document.getElementById("next");
const prev_button = document.getElementById("prev");

全てのスライダー要素にslider-indexという番号をつけます。

function set_index(){
	for(let l=0;l<slider_items.length;l++){
		slider_items[l].setAttribute("slider-index", [l]);
		 l >= 0 && l < 3 ? slider_items[l].classList.add( 'slide_area' ) : false;
     prev_button.classList.add( 'disable' );	// 最初の位置のときは戻るボタンは使えなくする
	}
}

このとき0,1,2の位置のものにはslide_areaクラスをつけて見えるようにしています。これがスライダーで見えるエリアにある要素ということです。

それから初期位置のときは左に何もないはずなので「戻る」ボタンを使えなくしておきます。

set_index();

関数を定義しただけになっているので実行します。参考にしたものではpromiseを呼び出しているのですが、正直promise.resolveがよくわからなかったので使えませんでした。set_index処理をさせてからアローボタン処理に移った方がいいのは確かですが、とりあえずただの実行でも機能は動いています…。promiseは今後きちんと勉強します。

次へボタン、戻るボタンの操作

「次へ」、「戻る」のアローボタンを押したときに何が起こるかですが、「戻る」ボタンを例に図示しました。

コードとそれぞれの説明です。

function prev_slide(){
	next_button.classList.remove("disable");// 次へボタンを使えるようにする
	const current_items = document.querySelectorAll(".slide_area");// スライダーエリアにある要素取得
	const first = slider_list.firstElementChild.getAttribute( 'slider-index' );//最初の要素の番号を取得、0
	for(let n=0;n<current_items.length;n++){
		if( n=== 0){
			const prev_element = current_items[n].previousElementSibling;//一つ前の要素をprev_elementにした

			const first_current = Number(current_items[n].getAttribute("slider-index"))-1;
   //スライダーエリア0の位置の要素のindex番号から1を引いたものをfirst_currentに定義
			Number( first ) === first_current ? prev_button.classList.add( 'disable' ) : false;
   //スライダーエリア0の位置の前の要素のindex番号が最初の要素だったら、前へボタンは使えなくする
			prev_element.classList.add("slide_area");//一つ前の要素をにスライドエリアクラスをつけて見えるようにした
		}
		n === 2 ? current_items[n].classList.remove('slide_area') :false;
  //スライドエリアの2の位置にある要素はスライドエリアクラスを外して見えないようにする
	};
}

これは「次へ」ボタンのときもほぼ同じ仕組みで、スライドエリアの0の位置にある要素が次は外れる要素、次にスライドエリアに入る要素にスライドエリアクラスを付けたり外したりして制御します。

あとはもうこれ以上要素がないときはボタンを使えなくすることが大事ですね。

一応「次へ」ボタンとボタンイベントのコードを載せておきます。全体像はCodePenを見てください。


function next_slide(){
	prev_button.classList.remove("disable");
	const current_items = document.querySelectorAll(".slide_area");
	const last = slider_list.lastElementChild.getAttribute("slider-index");
	for(let m=0;m<current_items.length;m++){
		if( m === 0){			current_items[m].classList.remove("slide_area")};
		if( m === 2){
			const next = current_items[m].nextElementSibling;
			const last_current = Number(current_items[m].getAttribute("slider-index"))+1;
			next.classList.add("slide_area");
				 Number( last ) === last_current ? next_button.classList.add( 'disable' ) : false;
		};		
	}
}

// イベント処理
next_button.addEventListener('click', function(){next_slide();});
prev_button.addEventListener('click', function(){prev_slide();});

スライダーって地味に見えますけど、JavaScriptで動かそうとするとかなり大変でした。for文で要素を回して処理をさせようとするんですが、要素がとれてないとclassListのエラーが出てきたり。

最近本当にJavaScriptを原理からちゃんと勉強しないとわからないなと思い始めています。

コメント