前回作ったスライドショーにドットページネーションを付けます。だんだん、それっぽくなってきたのが嬉しいです!
今回追加した仕様
スライドショーにドットのページネーションを作りましょう
それぞれのドットではクリッカブルになっていて、押下するとその画像に切り替わります。
それとともに1/5も切り替わります。
完成したもの
最終的には、このようなスライドショーを作ることができました。
実装
ドットページネーションの切り替えは、初め下記のようなコードにしました。この時は、ドットのボタン、ひとつひとつにクリックイベントを設定していたので、パフォーマンス的によくないコードです。
//ドットをクリックした時の動き
const addClickEventForDotPagination = (sliderData) => {
const dotPaginetions = document.getElementsByClassName("dot-pagination__item");
for(const dotPagination of dotPaginetions ){ //li要素ひとつひとつに設定するためループ処理
dotPagination.addEventListener("click",function(){
const arrayPaginations = [...dotPaginetions];
currentIndex = arrayPaginations.indexOf(this);
switchSlider(sliderData);
resetAutoPlay(sliderData);
});
}
}
//スライドの切り替えに関わる関数をまとめる関数
const switchSlider = (sliderData) => {
changeCurrentNumber(); //ページ番号の変更
switchSliderItems(); //画像の切り替え
switchPaginations(); //ページネーションの切り替え
switchDisabledButton(sliderData); //最初と最後のページでは、矢印ボタンをdisabled
}
レビュー
今回は、はるさん、ちひろさん、さえさんにレビューをして頂きました!いつも本当に、ありがとうございます。
イベントの委譲
最初にPRしたコードでは、ドットページネーション一つ一つに対して、イベントを設定していたので、パフォーマンス的にあまりよくないとご指摘いただきました。親要素である、ulにイベントハンドラを登録しておき、子要素にも伝播させる方法を教えて頂きました。イベントの委譲と言うそうです。
ループ処理がなくなってスッキリしました!パフォーマンス的にもいいらしいです。
ちなみに、イベントの委譲をしているときのthisは、イベントハンドラを設定している親要素になります。
const addClickEventForPagination = (sliderData) => {
const paginations = document.getElementById("js-pagination");
const arrayPaginations = [...document.getElementsByClassName("js-pagination__item")];
paginations.addEventListener("click",function(e){
//イベントハンドラを登録した要素は何もしない
if(e.currentTarget === e.target){
return;
}
sliderStatus.currentIndex = arrayPaginations.indexOf(e.target);
switchSlider(sliderData);
resetAutoPlay(sliderData);
});
}
こうすることで、親要素に設定したイベントが、子要素に伝播します。親から子へイベントを伝えることを、バブリング、子から親に伝播させることをキャプチャリングと言うそうです。キャプチャリングを使うことはあまりないようです。
e.targetとcurrentTarget
子要素と子要素の間の余白をクリックするとエラーになるとレビューを頂いたので、current.Targetがtargetの時は、何もしないようにコードを追記しました。
//イベントハンドラを登録した要素は何もしない
if(e.currentTarget === e.target){
return;
}
e.targetは、イベントの発生した要素なので、クリックした子要素のliです。
currentTargetは、イベントハンドラが登録されている要素なので、親要素であるulです。
コンソールログで見ると、e.targetはクリックしたli要素<li class=”js-pagination__item”></li>が返ってきます。currentTargetは<ul class=”js-pagination”><li class=”js-pagination__item”></li</ul>が返ります。
event.targetは、イベントバブルのイベントを開始したDOM要素を返すプロパティ。 イベントバブルとは、子要素のイベントが発生すると、その親要素や先祖要素の同じタイプのイベントが発生すること。
http://alphasis.info/2013/09/javascript-dom-eventobject-target/#:~:text=event.target%E3%81%AF%E3%80%81%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%83%90%E3%83%96%E3%83%AB,%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%80%82
感想
JavaScriptを見たことがあっても、何が書いてあるかわからないところから、スライドショーを作れるようになりました。すごい進歩したのが嬉しいです。
少し長くなったので、オートプレイ機能については次回の記事にしようと思います。
次回追加する仕様
・3秒毎に次のスライドに自動で切り替わるauto
機能
私が所属しているフロントエンドエンジニアを目指す方のための塾 「もりけん塾」の森田賢二先生のTwitterはこちら!
【募集】フロントエンド、とりわけJavaScriptを教えてもらいたい塾生を募集しています。条件はありますが、お金は頂きません。詳しくはDMください#JavaScript教えてもらいたい方#駆け出しのエンジニアと繋がりたい
— フロントエンドエンジニア (@terrace_tech) April 18, 2020
わたしについて👉https://t.co/FETVmMT5AY
先生のブログ「武骨日記」はこちら!