[js]Splideの導入とGlightboxとの組み合わせ

swiperの重さが気になるお年頃。

はじめに

ECの商品ページの画像部分とかが挙げやすい例で、画像スライダーの出番は地味に多い。

地味に多いので動作は軽くしたい。

だから脱jQueryは割と早いうちから言われていた。

非jQueryなら何でも良いかといえばそうでもない。

使い勝手が良くても必要な機能が限られていたら、無用の長物でしかない。
jQueryの有無だけでは測れない。

swiper.jsはかなり強力なjsだから、思考停止してこれ一本でいってもいいのだけど、他にもないかと考えたらSplideというのが近年台頭してきてるらしい。

だからSplideの使い方と、ついでだからポップアップもそれに合わせて何があるかって感じの話。

Splideとは

Splide – アクセシビリティに配慮した軽量・高機能スライダー
アクセシビリティに配慮した軽量・高機能スライダー。ほかのライブラリに依存せず、Lighthouseのエラーもありません。

国産らしい。
嬉しいですね。

Splideの導入

大枠はこんな感じ。

<html>
<head>
    [略]
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css" integrity="sha256-5uKiXEwbaQh9cgd2/5Vp6WmMnsUr3VZZw0a8rKnOKNU=" crossorigin="anonymous">
</head>
<body>
<div class="splide" id="main_carousel" role="group" aria-label="Splideの基本的なHTML">
    <div class="splide__track">
        <ul class="splide__list">
            <li class="splide__slide"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=01" alt="" loading="lazy"></li>
            <li class="splide__slide"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=02" alt="" loading="lazy"></li>
            <li class="splide__slide"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=03" alt="" loading="lazy"></li>
            <li class="splide__slide"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=04" alt="" loading="lazy"></li>
        </ul>
    </div>
</div>
    [略]
    <script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js" integrity="sha256-FZsW7H2V5X9TGinSjjwYJ419Xka27I8XPDmWryGlWtw=" crossorigin="anonymous"></script>
    <script>
        new Splide('#main_carousel').mount();
    </script>
</body>
</html>

本体であるjsとcssを読み込んで、カルーセルと紐づけて発火させる。

jsはカルーセルよりも後で記述しないと発火しないので、</body>の手前に書く。

オプション周りも充実してるので、せっかく入れたのに、みたいなことはぱっと見ではなさそう。

breakpointsがちゃんと用意されているし、カルーセル化のオンオフも問題なく組み込める。

const productSlider = new Splide('#main_carousel',{
    type: 'loop',
    perPage: 1,
    mediaQuery: 'min', // モバイルファースト
    breakpoints: {
        768: {
            destroy: true, // PCサイズになったらスライダーを破壊
        },
    },
})
productSlider.mount();

Splide()を直接マウントさせても良いんだけど、↑みたいに変数を作って分けておくと汎用性高まるかも。

使用感

他のカルーセルと同様に、読み込み時に高さが保持されてないのでガクっとなる。

だからこちら側で予めカルーセル領域の高さを確保しておくのが無難。
ページ内スクロールを仕込んだときにズレる原因になったりチカチカしてだるかったり、Googleの「PageSpeed Insights」の評価対象だったりするのでカバーしておきたい。

ポップアップの導入

非jQueryだからポップアップも同様の組み合わせにしたい。

「Glightbox」が良いらしい。

GLightbox | A pure Javascript lightbox

組み込みはこんな感じになる。

<html>
<head>
    [略]
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glightbox@3.3.1/dist/css/glightbox.min.css" integrity="sha256-bT9i1NF5afnHDpQ4z2cQBHJQGehoEj8uvClaAG+NXS0=" crossorigin="anonymous">
</head>
<body>

<a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=01" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=01" alt="" loading="lazy"></a>
<a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=02" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=02" alt="" loading="lazy"></a>
<a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=03" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=03" alt="" loading="lazy"></a>

    [略]
    <script src="https://cdn.jsdelivr.net/npm/glightbox@3.3.1/dist/js/glightbox.min.js" integrity="sha256-xnxZzfmAeTsCFsnenG6/aIQYg4girx5QsJQ546oon/M=" crossorigin="anonymous"></script>
    <script>
        const lightbox = GLightbox({
            touchNavigation: true,
            loop: false,
            closeButton: true,
        });
    </script>
</body>
</html>

classを付けるだけで稼働するのがヤバい。
jQueryかよってくらい手軽でヤバい。

ポップアップ上でスライドできるし、グループ化もできる。
すごい。

例えばphotoswipeを過去に使ってたけど、あそこまでの機能はいらないし追記が多かったりして、これならjQueryでよくね?って思ってたんだけどね。うれしいですね。

ということで、Splide+Glightboxが一つの正解なんじゃないですかね。
シンプルなカルーセル+ポップアップがほしかった。助かる。

<html>
<head>
    [略]
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css" integrity="sha256-5uKiXEwbaQh9cgd2/5Vp6WmMnsUr3VZZw0a8rKnOKNU=" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glightbox@3.3.1/dist/css/glightbox.min.css" integrity="sha256-bT9i1NF5afnHDpQ4z2cQBHJQGehoEj8uvClaAG+NXS0=" crossorigin="anonymous">
</head>
<body>
<div class="splide" id="main_carousel" role="group" aria-label="Splideの基本的なHTML">
    <div class="splide__track">
        <ul class="splide__list">
            <li class="splide__slide"><a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=01" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=01" alt="" loading="lazy"></a></li>
            <li class="splide__slide"><a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=02" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=02" alt="" loading="lazy"></a></li>
            <li class="splide__slide"><a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=03" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=03" alt="" loading="lazy"></a></li>
            <li class="splide__slide"><a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=04" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=04" alt="" loading="lazy"></a></li>
        </ul>
    </div>
</div>
    [略]
    <script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js" integrity="sha256-FZsW7H2V5X9TGinSjjwYJ419Xka27I8XPDmWryGlWtw=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/glightbox@3.3.1/dist/js/glightbox.min.js" integrity="sha256-xnxZzfmAeTsCFsnenG6/aIQYg4girx5QsJQ546oon/M=" crossorigin="anonymous"></script>
    <script>
        const lightbox = GLightbox({
            touchNavigation: true,
            loop: false,
            closeButton: true,
        });

        new Splide('#main_carousel').mount();
    </script>
</body>
</html>

おまけ:<head>内にまとめる方法

jQueryに慣れてるのもあって、<head>内で完結したい気持ちがある。

<head>に書くのに</body>にも書かなきゃって状況は正直気持ち悪い。

<html>
<head>
    [略]
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css" integrity="sha256-5uKiXEwbaQh9cgd2/5Vp6WmMnsUr3VZZw0a8rKnOKNU=" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glightbox@3.3.1/dist/css/glightbox.min.css" integrity="sha256-bT9i1NF5afnHDpQ4z2cQBHJQGehoEj8uvClaAG+NXS0=" crossorigin="anonymous">

    <script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js" integrity="sha256-FZsW7H2V5X9TGinSjjwYJ419Xka27I8XPDmWryGlWtw=" crossorigin="anonymous" defer></script>
    <script src="https://cdn.jsdelivr.net/npm/glightbox@3.3.1/dist/js/glightbox.min.js" integrity="sha256-xnxZzfmAeTsCFsnenG6/aIQYg4girx5QsJQ546oon/M=" crossorigin="anonymous" defer></script>
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        const lightbox = GLightbox({
            touchNavigation: true,
            loop: false,
            closeButton: true,
        });

        new Splide('#main_carousel').mount();
    });
    </script>
</head>
<body>
<div class="splide" id="main_carousel" role="group" aria-label="Splideの基本的なHTML">
    <div class="splide__track">
        <ul class="splide__list">
            <li class="splide__slide"><a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=01" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=01" alt="" loading="lazy"></a></li>
            <li class="splide__slide"><a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=02" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=02" alt="" loading="lazy"></a></li>
            <li class="splide__slide"><a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=03" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=03" alt="" loading="lazy"></a></li>
            <li class="splide__slide"><a href="https://placehold.jp/3d4070/ffffff/800x800.png?text=04" class="glightbox"><img src="https://placehold.jp/3d4070/ffffff/800x800.png?text=04" alt="" loading="lazy"></a></li>
        </ul>
    </div>
</div>
</body>
</html>
  • jsファイルを読み込む場合は「defer」を追加する
  • jsを直接書き込む場合は「DOMContentLoaded」で囲う

この2つで対応できる。

コメント

タイトルとURLをコピーしました