[js]PhotoSwipe v5を触ってみた

以前から結構経った気がしたけどそうでもなかった。

作例

cdnのファイルと本家のコードを使いまわし。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.css" integrity="sha512-aYZebRqOKTENn+6dnGG8LESiKfRv+2Oi1UTr/u47p0DKdYCih17xTP+/MrTzDPTSvdpSgTwzp5aB3QfO1I+mEA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script type="module">
import PhotoSwipeLightbox from 'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe-lightbox.esm.js';
const lightbox = new PhotoSwipeLightbox({
  gallery: '#gallery--getting-started',
  children: 'a',
  pswpModule: () => import('https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.esm.js')
});
lightbox.init();
</script>
</head>
<body>
    <div class="pswp-gallery pswp-gallery--single-column" id="gallery--getting-started">
        <a href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/2/img-2500.jpg" 
          data-pswp-width="1669" 
          data-pswp-height="2500" 
          target="_blank">
          <img src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/2/img-200.jpg" alt="" />
        </a>
        <!-- cropped thumbnail: -->
        <a href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/7/img-2500.jpg" 
          data-pswp-width="1875" 
          data-pswp-height="2500" 
          data-cropped="true" 
          target="_blank">
          <img src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/7/img-200.jpg" alt="" />
          Cropped
        </a>
        <!-- data-pswp-src with custom URL in href -->
        <a href="https://unsplash.com" 
          data-pswp-src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/3/img-2500.jpg"
          data-pswp-width="2500" 
          data-pswp-height="1666" 
          target="_blank">
          <img src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/3/img-200.jpg" alt="" />
        </a>
        <!-- Without thumbnail: -->
        <a href="http://example.com" 
          data-pswp-src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/5/img-2500.jpg"
          data-pswp-width="2500" 
          data-pswp-height="1668" 
          target="_blank">
          No thumbnail
        </a>
        <!-- wrapped with any element: -->
        <div>
          <a href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/6/img-2500.jpg"
            data-pswp-width="2500" 
            data-pswp-height="1667" 
            target="_blank">
            <img src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/6/img-200.jpg" alt="" />
          </a>
        </div>
      </div>
</body>
</html>

<head>でscriptをまとめられるのがすごくいい。

4.1.1と変わったところ

かなり変わってる。発火元の組み方が柔軟になったし、ポップアップ用のhtmlの組み込みが必要なくなったし、jsファイルの読み込みがコード内で行われるようになった。

元々動作に文句のつけようのないものだったけど、膨大なコードを入れなきゃいけなかったのがかなりしんどかった。ここまでスッキリしたのはとんでもない良アップデート。相変わらずシンプルなお陰でカスタマイズする必要もないレベル。

複数設置する場合

constでまとめてるアレなので、複製して変数名を変えて各々組めば良い。

import PhotoSwipeLightbox from 'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe-lightbox.esm.js';
//1個目
const lightbox = new PhotoSwipeLightbox({
  gallery: '#gallery--getting-started',
  children: 'a',
  pswpModule: () => import('https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.esm.js')
});
lightbox.init();
//2個目
const lightbox2 = new PhotoSwipeLightbox({
  gallery: '#gallery--getting-started2',
  children: 'a',
  pswpModule: () => import('https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.esm.js')
});
lightbox2.init();

グループを分けたいだけで動作一緒でいいならgallery部分を増やしてもいけた。

import PhotoSwipeLightbox from 'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe-lightbox.esm.js';
const lightbox = new PhotoSwipeLightbox({
  gallery: '#gallery--getting-started,#gallery--getting-started2',
  children: 'a',
  pswpModule: () => import('https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.esm.js')
});
lightbox.init();

というか、idじゃなくてclass指定すれば良かったりする。

その他オプション

公式が書いてある。

Options | PhotoSwipe
bgOpacity

キャプションは追加したい気持ちあるけど基本的にそのままでよくない?って思っちゃったりして。

data属性は必須

作例の<a>に入ってるdata属性は必ず入れること。入れないと画面いっぱいに表示されることになる。

<a href="https://placehold.jp/1600x900.png" data-pswp-width="1600" data-pswp-height="900" target="_blank"><img src="https://placehold.jp/1600x900.png" alt=""></a>

しかしいちいち手打ちするのはめんどくさい。サイズ統一ルールを作るなら良いけど、サイズがばらばらになることだって普通にあるわけで。ということでjsで済ませてしまおうという話。

v4のときにもやった。

dataの組み方が変わってるのでそれに合わせていく。

こんな感じであったとして。

<ul class="image_list">
    <li><a href="https://placehold.jp/1600x900.png" target="_blank"><img src="https://placehold.jp/1600x900.png" alt=""></a></li>
    <li><a href="https://placehold.jp/1600x900.png" target="_blank"><img src="https://placehold.jp/1600x900.png" alt=""></a></li>
    <li><a href="https://placehold.jp/1600x900.png" target="_blank"><img src="https://placehold.jp/1600x900.png" alt=""></a></li>
    <li><a href="https://placehold.jp/1600x900.png" target="_blank"><img src="https://placehold.jp/1600x900.png" alt=""></a></li>
</ul>

こうなる。

    <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.css" integrity="sha512-aYZebRqOKTENn+6dnGG8LESiKfRv+2Oi1UTr/u47p0DKdYCih17xTP+/MrTzDPTSvdpSgTwzp5aB3QfO1I+mEA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <script type="module">
        $(window).one('load',function(){
            $('.image_list').find('a').each(function(){
                var image = new Image();
                image.src = $(this).attr('href');
                console.log(image.width);
                $(this).attr({'data-pswp-width':image.width,'data-pswp-height':image.height});
            });
        });
        import PhotoSwipeLightbox from 'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe-lightbox.esm.js';
        const lightbox = new PhotoSwipeLightbox({
          gallery: '.image_list',
          children: 'a',
          pswpModule: () => import('https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.2.2/photoswipe.esm.js')
        });
        lightbox.init();
    </script>

jQueryで書いてるもんだからライブラリ読ませないと動かないので注意。

前回の記事と違って、<a>のリンク先の画像から取得した。こうすればサムネ用に小さい画像を使ってたときの対策になる。

注意:20230106追記

jsでdataを付ける発想は冴えてるんだけど、残念ながら安定しない。

画像の読み込みが完了しないでjsが発火すると原寸サイズを拾えずに「0」になって、結果表示がバグる。いろいろ試してみたんだけど、今回のようにリンクをクリックして初めて画像を読み込む場合はjs発火のタイミングが悪い。

それならってことでpreloadしたり、body内にdisplay:none;で設置したりしてみたけど、初回読み込みは上手く動くんだけど、既に表示してある状態(キャッシュがある状態)で更新をかけると安定しない。

今回試したのはWP上だった。以前導入したときはWPじゃなくてサムネも拡大も同一ファイルだった。そのせいか、上手くいってた。

ということで、無理っぽかったらdata属性はベタ打ちすることも視野に入れておく必要がある。

コメント

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