テレビの番組表やタイムテーブルなどに活用できるSwiperスライダーを実装してみる(備忘録)

今回はテレビの番組表やタイムテーブルなどに活用できるSwiperスライダーを実装していく。

実装自体はそこまで難しくないが、これまで紹介してきたような画像のスライダーとは別の見た目になるので、一から説明していければと思う。

今回実装するのは、よくあるテレビ局やラジオなど、番組何月何日にこんな番組が放映されるなどのような時に、結構使えるようなものかと思う。いわゆる番組表やタイムテーブルみたいなものに使える感じだ。

実際に実装したデモは下記になるが、今回は画像は使わずにテキストだけ使用してみた。最後のコンテンツの中身がはみ出させているのは、ページを見る人に続きがあることがわかるようにするためである。

それでは実装に入っていく。

HTMLの記述について

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Swiperスライダー</title>
  <link rel="stylesheet" href="../reset.css">
  <link rel="stylesheet" href="https://unpkg.com/swiper@8/swiper-bundle.min.css" />
</head>
<body>
  <main>
    <div class="swiperCont">
      <div class="swiper mySwiper">
        <ul class="swiper-wrapper">
          <li class="swiper-slide">
            <h4>4/1(月)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/2(火)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/3(水)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/4(木)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/5(金)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/6(土)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/7(日)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/8(月)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/10(火)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/11(水)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/12(木)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/13(金)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/14(土)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/15(日)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/16(月)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/17(火)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/18(水)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/19(木)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/20(金)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/21(土)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/22(日)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/23(月)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/24(火)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/25(水)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/26(木)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/27(金)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/28(土)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/29(日)</h4>
            <p>予定が入ります</p>
          </li>
          <li class="swiper-slide">
            <h4>4/30(月)</h4>
            <p>予定が入ります</p>
          </li>
        </ul>
      </div>
      <div class="swiper-button-prev"></div>
      <div class="swiper-button-next"></div>
    </div>
    <section>
      <div class="ly_inner" id="menu1">
        <h2>menu1</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu2">
        <h2>menu2</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu3">
        <h2>menu3</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu4">
        <h2>menu4</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu5">
        <h2>menu5</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
  </main>
  <script src="https://unpkg.com/swiper@8/swiper-bundle.min.js"></script>
  <script src="style.js"></script>
</body>
</html>

スライダー部分の記述は下記部分になる。これまで紹介してきた内容で十分に対応できる。

<div class="swiperCont">
  <div class="swiper mySwiper">
    <ul class="swiper-wrapper">
      <li class="swiper-slide">
        <h4>4/1(月)</h4>
        <p>予定が入ります</p>
      </li>
		・・・
      <li class="swiper-slide">
        <h4>4/30(月)</h4>
        <p>予定が入ります</p>
      </li>
    </ul>
  </div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

swiperContを指定しているのは、スライダーの左右のナビゲーション(矢印)部分をスライダーの外側に出したり、上下の余白をつけたりなどの目的があって設定している。

あとはswiperの公式ドキュメントをもとに、ソースを記述しているが、今回はulタグを使用して、liタグがそれぞれのスライダーに当てはまるようにコードを書いている。

swiper-button-prevとswiper-button-nextはナビゲーション(矢印)部分にあたる。この見た目も変えることができるが今回は以前書いたブログのデザインと一緒にしている。よく見かけるようなデザインは縦長長方形の中に矢印があるようなものが多いかなと個人的には思っている。

CSSの記述について

@charset "utf-8";

/* ==========================
  初期設定
========================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  position: relative;
  word-wrap: break-word;
}

img {
  width: 100%;
}

/* ==========================
  swiperslider
========================== */
.swiperCont {
  width: 80%;
  margin: 20px auto;
  position: relative;
}

.swiper {
  width: 100%;
}

.swiper-button-next,
.swiper-rtl .swiper-button-prev,
.swiper-button-prev,
.swiper-rtl .swiper-button-next {
  background-color: #ccc;
  border-radius: 50%;
  padding: 30px;
}

.swiper-button-next,
.swiper-rtl .swiper-button-prev {
  right: -70px;
}

.swiper-button-prev,
.swiper-rtl .swiper-button-next {
  left: -70px;
}

.swiper-button-next:focus,
.swiper-rtl .swiper-button-prev:focus,
.swiper-button-prev:focus,
.swiper-rtl .swiper-button-next:focus {
  outline: none;
}

.swiper-button-prev:after,
.swiper-rtl .swiper-button-next:after,
.swiper-button-next:after,
.swiper-rtl .swiper-button-prev:after {
  color: #fff;
  font-size: 24px;
}

.swiper-slide {
  background-color: #ccc;
  min-height: 120px;
  padding: 20px;
}
.swiper-slide h4 {
  margin-bottom: 10px;
  font-weight: bold;
  font-size: 20px;
}

@media screen and (max-width: 767px) {
  .swiperCont {
    width: 100%;
    padding: 0 70px;
  }

  .swiper-button-next,
  .swiper-rtl .swiper-button-prev {
    right: 10px;
  }

  .swiper-button-prev,
  .swiper-rtl .swiper-button-next {
    left: 10px;
  }

  .swiper-button-next,
  .swiper-rtl .swiper-button-prev,
  .swiper-button-prev,
  .swiper-rtl .swiper-button-next {
    padding: 24px;
  }

  .swiper-button-prev:after,
  .swiper-rtl .swiper-button-next:after,
  .swiper-button-next:after,
  .swiper-rtl .swiper-button-prev:after {
    font-size: 16px;
  }

}

/* ==========================
  コンテンツの中身
========================== */
.ly_inner {
  width: 100%;
  max-width: 1080px;
  margin: 100px auto;
  padding: 20px;
  background-color: #ccc;
}

.ly_inner h2 {
  font-size: 150%;
  font-weight: bold;
  margin-bottom: 30px;
}

.md_textblock>*+* {
  margin-top: 10px;
}

今回解説するのは下記の部分である。そのほかの部分は過去の記事で紹介しているので具体的には解説しない。

body {
  word-wrap: break-word;
}
.swiper-slide {
  background-color: #ccc;
  min-height: 120px;
  padding: 20px;
}

グレーの四角い枠を作るためにbackground-colorをcccで設定、最低限要素が入っていなくても高さを確保してあげたいのでmin-heightを120pxに設定、最後にpaddingを20pxに設定して見た目を整えた。

あとは、このグレーの四角い枠の中で文字が使われたとき、幅を狭めていくと文字が改行されずに枠からはみ出てしまう状態になっているのを修正するため、bodyに対して、word-wrapをbreak-wordに設定した。

JavaScriptの記述について

'use strict'

// swiperslider
const swiper = new Swiper('.mySwiper', {
  slidesPerView: 2.5,
  spaceBetween: 10,
  breakpoints: {
    768: {
      slidesPerView: 4.5,
      spaceBetween: 20,
    },
  },
  freeMode: true,
  grabCursor: true,
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
})

JavaScriptについては、そこまで変わったことはしていないが、一応解説していく。

slidesPerViewでスライダーが何個見えた状態にするかを決めることができるので、768px未満の時は2.5、768px以上の時は4.5と設定した。

続いて、spaceBetweenについてはスライダー間の幅を設定できる。こちらは768px未満の時は10、768px以上の時は20と設定した。

ここで使われているbreakpointsはレスポンシブ対応をしたい時によく使うもので、任意の数字を設定することができる。

今回、新しく出てきたのがfreeModeとgrabCursorである。

freeModeはtrueにすると、スライドするときに次のスライドで止まらずに、フリック操作やマウスでのドラッグ操作の強さに応じてスライダーが自由に追従してついていくような挙動になる。

一方grabCursorはtrueにすると、マウスのポインターをスライドに乗せると指のマークになる掴めることが視覚的にわかるようになってくれる。

あとはいつも通りnavigationを設定している。

以上で実装完了だ。