エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

Swiperを使ってみた

きっかけ

ルーセルスライダーでリストを表示したかったので調査した結果、swiperってライブラリが良さそうだったので、使ってみた。

公式サイト

swiperjs.com

実装内容・説明

Typescript使っているので、それに合わせて実装
jsの情報はいっぱい出てきたけど、typescriptは、あんまりなかったので、手探りだった。。。

動きは、全部swiperが付けてくれるので、こっちは、動きの定義とレイアウトの定義をしてあげるだけ。

完成イメージ

趣味全開で作ってるので、ご了承下さい。

html

まずは、見た目側
面倒くさいから、作ったので全部載せる。

<!DOCTYPE html>
<html lang="ja" class="h-100">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta name="Description" content="Enter your description here"/>

  <script src="/js/youtube.js"></script>
  <link rel="stylesheet" href="/style.css">
  <link rel="stylesheet" href="/youtube.css">
  <title>GalwWing</title>

</head>
<body class="h-100 bg-light">
<!-- 全ページを囲む要素 -->

<main class="h-100">
  <!-- サイトバーメニュー -->
  <!-- サイトバーメニュー -->

  <!-- 全ページの右のコンテンツ -->
  <div class="page-content main w-100">
    <div id="youtube">
      <div id="player"></div>
    </div>
  </div>

  <!-- Slider main container -->
  <div class="swiper">
    <!-- Additional required wrapper -->
    <div class="swiper-wrapper">
    </div>

    <!-- If we need pagination -->
    <div class="swiper-pagination"></div>

    <!-- If we need navigation buttons -->
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>

    <!-- If we need scrollbar -->
    <div class="swiper-scrollbar"></div>
  </div>

</main>
</body>

</html>

重要なのは、<div class="swiper">とその中の定義。
基本的に、公式サイトで乗ってるレイアウトそのまま貼り付ければ、行けるはず。
リストで表示したいデータを、<div class="swiper-wrapper">に追加してやる必要がある。
とりあえず試す場合は、公式サイトに以下のようなサンプルが記載されている

<!-- Slider main container -->
<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <div class="swiper-slide">Slide 1</div>
    <div class="swiper-slide">Slide 2</div>
    <div class="swiper-slide">Slide 3</div>
    ...
  </div>
  <!-- If we need pagination -->
  <div class="swiper-pagination"></div>

  <!-- If we need navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>

  <!-- If we need scrollbar -->
  <div class="swiper-scrollbar"></div>
</div>

typescript

どちらかというと、こっちの実装で苦労した。
webpackが絡んでくると、typescript系の実装は、敷居が10段くらい高くなるんだよね。。。

まずは、npmでモジュールをインストール

npm install swiper

実装しているクラスが、雑音多いので、実装部分だけ抜粋。

// import Swiper styles
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';

// コアバージョンに加えて、ナビゲーションとページネーションを追加する
import Swiper, { Navigation, Pagination, SwiperOptions } from 'swiper';

// モジュールを使用可能に
Swiper.use([Navigation, Pagination]);

// 省略

window.onload = () => {
  const swiperParams: SwiperOptions = {
    direction: 'horizontal',
    slidesPerView: 3,
    spaceBetween: 50,
    loop: false,
    autoplay: true,
    pagination: {
      el: '.swiper-pagination',
    },
    navigation: {
      nextEl: '.swiper-button-next',
      prevEl: '.swiper-button-prev',
    },
    scrollbar: {
      el: '.swiper-scrollbar',
    },
  };

  const swiper = new Swiper('.swiper', swiperParams);
};

SwiperOptions で動きを定義。
paginationで、位置情報の「・・・」みたいなやつを表示するタグを指定。
nabigationは、移動するためのボタンを表示するタグを指定。
scrollbarは、なんだっけ。。。?思い出せん。。。
あと、cssのインポートとuseでswiperに使う情報を連携してあげる必要がある。
cssの定義は、webpackに起因してくるので、おまじない程度に考えてもらえればいいはず。

公式サイトだと、directionverticalになっているけど、それだと「・・・」が縦に出てきてしまうので、イメージと違うから、horizontalを指定。

あとは、なんとなくのイメージで分かると思うから、大雑把に説明(今までの説明も大雑把な気がするが。)
slidesPerView:画面に表示するデータ数
spaceBetween:データの感覚 loop:最初と最後の要素に来た際、サイクルさせる。falseにすると、ボタンが非活性になる。
autoplay:動きをちゃんと検証してないけど、たぶん、自動で移動してリストの内容を見せてくれると思う。

Swiperのインスタンス生成するときにオプションとswiperの定義をしているタグを指定することで、完成イメージの表示になる。
ただ、最後の難問として、webpackの定義がいる。

webpack

はっきり言って、typescriptを難しくしている犯人は、webpackだと思っている。
typescriptの環境作れていること前提で話すが、必要な部分はcss-loader付近の定義

const config = {
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/i,
        loader: 'ts-loader',
        exclude: ['/node_modules/'],
        options: {
          transpileOnly: true,
          configFile: process.argv.mode === 'production' ? 'tsconfig.json' : 'tsconfig.dev.json',
        },
      },
      {
        test: /\.css$/i,
        use: [stylesHandler, { loader: 'css-loader', options: { url: false } }],
        sideEffects: true, // production modeでもswiper-bundle.cssが使えるように
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
        type: 'asset',
      },

      // Add your rules for custom modules here
      // Learn more about loaders from https://webpack.js.org/loaders/
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
};

この定義を入れることで、最終的にビルドしたjsに、cssの定義を含めることができるはず。。。
なんとなく、雰囲気で実装してる。たしか、以前調べたときに、そんなだった気がする。
ライブラリにcssが含まれているときに、htmlにnode_moduleのパス書きたくなかったので、この定義をした気がする、全然気にならない人は、typescripでインポートしたファイルへのパスをhtmlで定義してやれば、webpackに書かなくてもイケる気がする。
個人的に、そのやり方は気に食わないが。

参考サイト

雑記

jquery非依存は、探せばあるものだな。
以前に関わったプロジェクトで、jquery起因でパフォーマンスが出ない事例を聞いていたので、なるべく避けるようにしているが、jquery非依存ライブラリの日本語の情報は、まだ少ない気がする。
あとは、定義の仕方で悩むことが多かった。
いろんなのが起因してビルドエラーになっていたり、ビルド忘れていて定義が反映されないから、定義内容を何度も見返したりしていた。
PONに気づくと、アハ体験が起きたあとに、落胆するんだよね。。。
他の人は、どうなんだろう?怒りが湧くのか、笑ってしまうのか、落胆するのか、あるいは、別の反応が起こるのか。

GWは、ホロライブの動画を結構見た気がする。
ホロライブを見ると沼にハマるって意味が分かったわ。。。
きっかけがあると、人間関係が見えてくるようになって、他のホロメンの動画を見てしまい、その連鎖が止まらなくなるんだよね。。。

youtubeのUIが、最近、気に食わないのだが、俺だけ?
あと、チャットがウザいから非表示にしたいんだけど、設定で非表示にできないのかな?
たぶん、あれのせいでパフォーマンス落ちてる気がするんだよね。。。
マシンスペック上げられればいいんだけど、cpu交換って、なんか怖い。