もりけん塾のJavaScript課題18で、Vanilla JSを使用したスライドショー作りにチャレンジしました。
こんにちは。Webコーダーのはるです。
現在、所属している「もりけん塾」でハンズオン課題 に取り組み、レビューをいただいています。
今日は、課題18 についてアウトプットをしていきます。
(前回までのアウトプットは、こちらです。)
実装する過程で学んだことを、学習ノートとして記録していきます。
認識の間違えている箇所がありましたら、お問い合わせからご指摘いただけるとうれしいです。
Vanilla JSでスライドショーを実装する②
今回、取り組んだ課題はこちらです。
(もりけん先生のJavaScriptハンズオン課題より)
前回作成したスライドショーに、ドットページネーションとオート機能を追加しました。
前回の ”スライドショーを実装する①” はこちら
作成したJSONデータ
こちらにまとめています。
ドットページネーションの基本機能
ドットページーネーションを作成↓
function renderListOfPagination(data) {
const paginationList = document.getElementById("js-pagination-list");
const fragment = document.createDocumentFragment();
for (let i = 0; i < data.length; i++) {
const li = document.createElement("li");
const Button = document.createElement("button");
li.classList.add("pagination__item","js-pagination-item");
li.dataset.index = `${i}`;
Button.classList.add("pagination__btn","js-pagination-btn");
Button.dataset.index = `${i}`;
//JSONデータでdisplay:trueの場合はis-activeを付与
data[i].display && li.classList.add("is-active");
fragment.appendChild(li).appendChild(Button);
}
pagination.insertAdjacentElement("afterbegin",paginationList).appendChild(fragment);
}
ドットページネーションを切り替える↓
function switchPagination(number) {
const ul = document.getElementById("js-pagination-list");
const paginationItems = [...document.getElementsByClassName("js-pagination-item")];
const activeItem = ul.querySelector(".is-active");
activeItem.classList.remove("is-active");
paginationItems[number].classList.add("is-active");
}
ul.querySelector(".is-active");で現在activeになっているドットを探し、activeをremove。
- <li>を配列にまとめ、引数に渡したnumber番目にactiveを付与する。
swicthPagination()を次の2つのシーンで実行しました。
next/previousボタンをクリックした時
この時、swicthPagination()の引数には現在is-activeのindexが入る。
const addEventListenerForButton = (dataLength) => {
const buttons = document.querySelectorAll(".js-button-arrow");
buttons.forEach((button) => {
button.addEventListener ("click", (e) => {
let currentIndex = getCurrentIndex();
e.currentTarget.id === "js-button-next" ? ++currentIndex : --currentIndex;
switchImg(currentIndex);
switchPagination(currentIndex);
incrementCurrentIndex(currentIndex);
toggleButtonDisabled(dataLength);
initAutoMoveSlide(dataLength);
})
})
}
また、元々nextボタンとpreviousボタンを別の関数に分けていましたが、
レビューをいただき1つの関数にまとめることができました。
e.currentTarget.id === "js-button-next" ? ++currentIndex : --currentIndex;
クリックした時に、buttonのidがjs-button-nextだったときは++currentIndex、
そうでない時は--currentIndexとしました。
++のことをインクリメント演算子と呼び、1を加算して値を返すものです。
前置きで++Aとするとインクリメント後の値を返し、
後置きでA++とするとインクリメント前の値を返すと知りました。
paginationのドットボタン自体をクリックした時
この時、swicthPagination()の引数にはクリックしたindexが入る。
const addEventListenerForPagination = (dataLength) => {
const paginationList = document.getElementById("js-pagination-list");
paginationList.addEventListener ("click", (e) => {
//buttonとbuttonの間はクリック対象外にする
if (e.currentTarget === e.target) {
return;
}
const clickedItemIndex = Number(e.target.dataset.index);
switchImg(clickedItemIndex);
switchPagination(clickedItemIndex);
incrementCurrentIndex(clickedItemIndex);
toggleButtonDisabled(dataLength);
initAutoMoveSlide(dataLength);
})
}
ドットボタンの間をクリックするとエラーが出るので、ボタン間のクリックは対象外にしました。
//buttonとbuttonの間はクリック対象外にする
if (e.currentTarget === e.target) {
return;
}
ここもレビューをいただき簡潔なコードになりました。ありがとうございます。
下記のようなページネーションで、
ドット以外のところ(以下の画像で紫の部分)をクリックすると
- e.currentTarget = ul
- e.target = ul
となるので処理が行われません。
ボタンをクリックすると、
- e.currentTarget = ul
- e.target = button
となり処理が発生します。
オート機能
オート機能を実装した後、
レビューをいただきオート機能をリセットする関数を追加しました。
//タイマー停止用のID
const intervalCount = { count: 0 };
function autoMoveSlide(dataLength) {
intervalCount.count = setInterval(() => {
let currentIndex = getCurrentIndex();
currentIndex++;
if (currentIndex === dataLength) {
currentIndex = 0;
}
switchImg(currentIndex);
switchPagination(currentIndex);
incrementCurrentIndex(currentIndex);
toggleButtonDisabled(dataLength);
}, 3000);
}
function initAutoMoveSlide(dataLength) {
clearInterval(intervalCount.count);
autoMoveSlide(dataLength);
}
- setIntervalを使用して3000msごとに自動でスライドが動くようにする。
- タイマー停止用のIDとしてintervalCountというオブジェクトを用意。
- オブジェクトにsetIntervalの実装を格納して、それらをclearInterval(ID)に引数として渡すことでタイマーを停止する。
- 停止したタイマーを
autoMoveSlide()で
再度動かす
元々let定義でタイマー停止用のIDを定義していたのですが、
レビューをいただきオブジェクトに代入する形にすればconst定義にできると学びました。
タイマーを停止→再稼働させるのは、ドットページネーションをクリックor next/previousボタン をクリックしたときにオート機能をリセットさせる必要があるためです。
今回のコード
※最低限の挙動を実装したため、レスポンシブ対応していません。プレビューはPCでご覧ください🙇♀️
//
学習に使用している本は、もりけん先生推奨の”JavaScript本格入門”です。
あとがき
今回レビューをしてくださった、さえさん(sae_prog)、もなかさん(ruby443n)ありがとうございました!
レビューで自分では気づけないところをご指摘いただけて、
機能もコードもレベルアップしました!とても勉強になりました。
お時間を割いていただきありがとうございました!
今日は以上です。
//
【もりけん塾で勉強しています】
もりけん先生(@terrace_tec)のHPはこちら