【もりけん塾】JavaScript課題18 -Vanilla JSでスライドショーを実装する②-

JavaScript

もりけん塾の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はこちら