jQuery Zoom プラグインのモーダルでの使い方をマスターしよう

目次

jQuery Zoomは画像のズーム機能を提供してくれるプラグイン

amazonの商品ページのように、画像をズームして詳細に確認したいときってありますよね。

服の購入を考えているとき、賃貸をさがしているとき、素材の細部を見たいとき。
画像をズームできたらありがたいです。

jQuery Zoomプラグインを使えば、この機能を簡単に実装できます!

【事前準備】jQuery Zoomの使い方

プラグイン名にも記載があるように、こちらはjQueryのプラグインになります。
なので事前にjQueryとプラグインを読み込んでおいてください。

CDNでの読み込み例はこちらになります。(2021/6/12時点)

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-zoom/1.7.21/jquery.zoom.min.js"></script>

ファイルをダウンロードする場合は下記URLから可能です。

ダウンロードしたファイルの中から下記のいずれかを使用します。
軽量化されているので、基本的にはjquery.zoom.min.jsを使用しましょう。

  • jquery.zoom.min.js
  • jquery.zoom.js

【基本コード】jQuery Zoomの基本的な使い方

HTML

<ul class="item-list">
  <li class="list">
    <div class="img">
      <img loading="lazy" class="item-img" src="●●●●" alt="">
    </div>
  </li>
</ul>

SCSS

.item-list{
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  
  .list{
    .img{
      overflow: hidden;
      
      img{
        max-width: 100%;
        height: auto;
      }
    }
  }
}

@media screen and (max-width: 767px) {
  .item-list{
    justify-content: space-between;
    padding: 0 2.6%;
    margin-top: 5px;
    
    .list{
      width: 48%;
      margin-top: 15px;

      .img{
        width: 100%;
        height: 86px;
      }
    }
  }
}

@media screen and (min-width: 768px) {
  .item-list{
    display: flex;
    justify-content: space-between;
    
    .list{
      width: 32%;

      .img{
        width: 100%;
        height: 240px;
      }
    }
  }
}

JavaScript

$('.img').zoom();

【基本コード】jQuery Zoomのモーダルでの使い方

HTML

<!-- モーダルのトリガー -->
<ul class="item-list">
  <li class="list">
    <div class="modal-trigger">
        <div class="img">
            <img loading="lazy" class="item-img" src="●●●●" alt="">
        </div>
    </div>
  </li>
</ul>


<!-- モーダル -->
<div class="modal-wrap">
    <div class="overlay"></div>
    <div class="modal-inner">
        <div class="img img-area">
            <img loading="lazy" class="base-img" src="">
        </div>
        <div class="modal-close"><i>×</i></div>
    </div>
    <!-- /.modal-inner -->
</div>

SCSS

.item-list{
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  
  .list{
    .modal-trigger{
      img{
        max-width: 100%;
        height: auto;
      }
    }
  }
}

.modal-wrap{
  position: fixed;
  left: 0;
  display: block;
  width: 100%;
  height: 100vh;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s linear 0s, visibility .3s linear 0s;
  
  &.show{
    top: 0;
    opacity: 1;
    visibility: visible;
    z-index: 10000;
  }
  
  .overlay{
    position: fixed;
    top: 0;
    left: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, .92);
    cursor: pointer;
    z-index: 10000;
  }
  
  .modal-inner{
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    background-color: transparent;
    opacity: 0;
    visibility: hidden;
    z-index: 10001;
    transition: opacity .3s linear .5s, visibility .3s linear .5s;
    transform: translate(-50%, -50%);
    
    &.show{
      opacity: 1;
      visibility: visible;
    }
    
    .modal-close{
      position: absolute;
      color: #fff;
      font-size: 24px;
      cursor: pointer;
    }
  }
}

@media screen and (max-width: 767px) {
  .item-list{
    justify-content: space-between;
    padding: 0 2.6%;
    margin-top: 5px;
    
    .list{
      width: 48%;
      margin-top: 15px;
      
      .modal-trigger{
        padding: 5.8%;
        
        .img{
          width: 100%;
          height: 88px;
        }
      }
    }
  }
  
  .modal-wrap{
    .modal-inner{
      width: 90%;

      .img-area{
        height: 200px;
      }

      .note{
        font-size: 10px;
      }

      .modal-close{
        top: -32px;
        right: 0;

        .icon{
          width: 24px;
        }
      }
    }
  }
}

@media screen and (min-width: 768px) {
  .item-list{
    display: flex;
    justify-content: space-between;
    
    .list{
      width: 30%;
      
      .modal-trigger{
        .img{
          width: 100%;
          height: 200px;
          overflow: hidden;
        }
        
        &:hover{
          opacity: 0.7;
        }
      }
    }
  }
  
  .modal-wrap{
    .modal-inner{
      max-width: 950px;

      .img-area{
        height: 77vh;

        .base-img{
          max-width: initial;
          height: 100%;
        }
      }

      .modal-close{
        top: -50px;
        right: 0;

        img {
          max-width: 85%;
        }
      }
    }
  }
}

JavaScript

//モーダル
//-------------------------------------------------------------
function modalFunc () {
  //変数の設定
  var $modalTrigger = $('.modal-trigger'),
      $modalWrap = $('.modal-wrap'),
      $overlay = $('.overlay'),
      $modalInner = $('.modal-inner'),
      $modalClose = $('.modal-close');
  
  //サムネイルをクリックしたときの挙動
  $modalTrigger.on('click', function(){
    $modalWrap.addClass('show');
    $modalInner.addClass('show');
  });
  
  //モーダルの×ボタンをクリックしたときの挙動
  $modalClose.on('click', function(){
    hideModal();
  });
  
  //オーバーレイ領域をクリックしたときの挙動
  $overlay.on('click', function(){
    hideModal();
  });
  
  //モーダルを消すための処理
  var hideModal = function () {
    $modalWrap.removeClass('show');
    $modalInner.removeClass('show');
  }
}




// モーダル内の画像をスイッチ
//-------------------------------------------------------------
function switchImageFunc() {
  var $modalTrigger =$('.modal-trigger'),
      $modalWrap =$('.modal-wrap'),
      $target = $modalWrap.find('.img-area').find('img');
  
  //トリガーをクリック
  $modalTrigger.on('click', function(e) {
    e.preventDefault();
    
    //トリガーに使用している画像のsrc属性の値を取得
    $src = $(this).find('img').attr('src');
    
    //モーダル内のimgタグに取得した値を設定
    $target.attr('src', $src);
    
   $('.img-area').zoom();
  })
}




// ベース画像のsrcをカラにする
//-------------------------------------------------------------
function deleteBaseImageSrc() {
  var $overlay = $('.overlay'),
      $modalClose = $('.modal-close');
  
  //モーダルの×ボタンをクリックしたときの挙動
  $modalClose.on('click', function(){
    deleteSrc();
  });
  
  //オーバーレイ領域をクリックしたときの挙動
  $overlay.on('click', function(){
    deleteSrc();
  });
  
  //ベースの画像読み込みパスをリセット
  function deleteSrc() {
    $('.base-img').attr('src', '');
  }
}




// ズーム用の画像を削除
//-------------------------------------------------------------
function removeOldImage() {
  var $overlay = $('.overlay'),
      $modalClose = $('.modal-close');
  
  //モーダルの×ボタンをクリックしたときの挙動
  $modalClose.on('click', function(){
    removeImg();
  });
  
  //オーバーレイ領域をクリックしたときの挙動
  $overlay.on('click', function(){
    removeImg();
  });
  
  //ズーム用の画像を削除
  function removeImg() {
    var $zoomImg = $('.modal-wrap').find('.img-area').find('.zoomImg');
    $zoomImg.remove();
  }
}


modalFunc();
switchImageFunc();
deleteBaseImageSrc();
removeOldImage();

コピペで使えるようになっているので、時間の無い方はぜひこのまま使ってみてください!
細かいスタイルやコードの調整はデザインに合わせて行ってください。

【Demo】jQuery Zoomのモーダル

See the Pen jQuery Zoom modal switch by さおさん (@saio-th) on CodePen.

【Point】jQuery Zoomの使い方

  • 対象の要素に対してzoomメソッドを実行するだけ
  • モーダルで使用する場合は、モーダルを開くタイミングでzoomメソッドを実行する
  • モーダルで使用する場合は、モーダルを閉じるタイミングでズーム用の画像を削除する

【解説】jQuery Zoomの基本的な使い方

基本的な使い方はとても簡単です。
対象の要素に対して、zoomメソッドを実行するだけです。

ページ読み込み時に次のコードを実行します。

$('.img').zoom();

なんとたった1行でズーム機能が反映されます!
これで画像を表示している範囲で、ズーム機能が有効になります。

.imgの部分は適宜修正してくださいね。

Demo

See the Pen jQuery Zoom basic by さおさん (@saio-th) on CodePen.

【解説】jQuery Zoomのモーダルでの使い方

モーダルでのズームも「【解説】jQuery Zoomの基本的な使い方」で紹介した記述で問題ありません。
デモを作成してみましたのでご覧ください。

Demo

See the Pen jQuery Zoom modal by さおさん (@saio-th) on CodePen.

モーダルのプログラムを除けば、zoomメソッドを実行するプログラムを1行記述するだけです。
カンタン!

しかし、ここでひとつ考えていただきたい。

デモのHTMLを見ていただいたらお分かりになると思いますが、ひとつのトリガーに対してひとつのモーダルを作成しています。
今回の場合は3つのトリガーがあるので、3つのモーダルを用意しています。

このやり方だと、画像を何十枚、何百枚と用意しなければいけない場合、どうなるでしょうか?
モーダルの数もそれに比例して増やしていかなければいけませんよね。

それは非常に非効率です。
コードも肥大化してしまいます。

できればモーダルはひとつにして、モーダル内の画像だけを切り替えて表示させたい
そうすればコード量も最小限で済みますし、効率的です。

モーダル内の画像を切りかえる方法

では、画像の切り替え方について説明します。
手順は次のとおりです。

  1. トリガーをクリックした瞬間に、トリガーに使われているサムネイル画像のsrc属性の値を取得する
  2. モーダル内にあらかじめ用意しているimgタグのsrc属性に、手順1で取得した値を設定する
  3. zoomメソッドを実行する
  4. モーダルを閉じた瞬間に、モーダル内のimgタグのsrc属性をカラにする

これを繰り返すことで、トリガーをクリックするたびにモーダル内の画像を切り替えます。

// モーダル内の画像をスイッチ
//-------------------------------------------------------------
function switchImageFunc() {
  var $modalTrigger =$('.modal-trigger'),
      $modalWrap =$('.modal-wrap'),
      $target = $modalWrap.find('.img-area').find('img');
  
  //トリガーをクリック
  $modalTrigger.on('click', function(e) {
    e.preventDefault();
    
    //トリガーに使用している画像のsrc属性の値を取得
    $src = $(this).find('img').attr('src');
    
    //モーダル内のimgタグに取得した値を設定
    $target.attr('src', $src);

   $('.img-area').zoom();
  })
}


// ベース画像のsrcをカラにする
//-------------------------------------------------------------
function deleteBaseImageSrc() {
  var $overlay = $('.overlay'),
      $modalClose = $('.modal-close');
  
  //モーダルの×ボタンをクリックしたときの挙動
  $modalClose.on('click', function(){
    deleteSrc();
  });
  
  //オーバーレイ領域をクリックしたときの挙動
  $overlay.on('click', function(){
    deleteSrc();
  });
  
  //ベースの画像読み込みパスをリセット
  function deleteSrc() {
    $('.base-img').attr('src', '');
  }
}

クリックしたサムネイルに使用している画像を取得して、
それをモーダル内の画像に設定して、
ズーム機能を実行します。

なのでzoomメソッドの実行タイミングはページ読み込み時ではなく、
サムネイルをクリックした瞬間
です。

「【解説】jQuery Zoomの基本的な使い方」で jQuery Zoom を実行したタイミングとは異なります。
やや複雑ですが、この点は押さえてください!

// モーダル内の画像をスイッチ
//-------------------------------------------------------------
function switchImageFunc() {
  var $modalTrigger =$('.modal-trigger'),
      $modalWrap =$('.modal-wrap'),
      $target = $modalWrap.find('.img-area').find('img');
  
  //トリガーをクリック
  $modalTrigger.on('click', function(e) {
    e.preventDefault();
    
    $src = $(this).find('img').attr('src');
    $target.attr('src', $src);

    //★トリガーをクリックしたときにzoomメソッドを実行
    $('.img-area').zoom();
  })
}

ひとつのモーダル内で画像を切りかえる際はモーダルを閉じるたびにズーム用の画像を削除しよう

画像の切り替え方はわかりました!

しかしまだ注意すべきポイントがあります。
それがこちらです。

  • jQuery Zoomは、ズームを終了したときにズーム用の画像を削除してくれない

この点を頭にいれて読み進めていただけると理解しやすいと思います。

まず、jQuery Zoomの仕様について簡単に説明します。

jQuery Zoomはzoomメソッドを実行すると、
ベースとなる画像の上に重なるように、ズーム用の画像を挿入してくれます
そしてその画像を拡大して表示することでズーム機能を提供してくれます

 zoomメソッドを実行すると…

図のように、下地となる画像の上にズーム用の画像を挿入してくれます。
ちなみに、ズーム用の画像は、配置されているベース用の画像とまったく同じものが挿入されます

そしてズーム機能を利用して画像を確認し終わったら、モーダルを閉じます。

ここまでの手順は次のとおりです。

  1. トリガーをクリックした瞬間に、トリガーに使われている画像のsrc属性の値を取得する
  2. モーダル内にあらかじめ用意しているimgタグのsrc属性に、手順1で取得した値を設定する
  3. zoomメソッドを実行してズーム用の画像を挿入
  4. モーダルを閉じた瞬間に、モーダル内のimgタグのsrc属性をカラにする

では、いまモーダルの中がどのような状態になっているか確認してみましょう。

はい、こうなってます。

そうなんです、モーダルを閉じたのにズーム用の画像は残ったままになっているんです!
なので…

「こっちの画像も確認してみよ。こっちの画像も確認してみよ。」

と画像を切り替えていくと、モーダル内はこうなってしまいます。

ズーム用の画像が削除されないので、モーダルを開くたびに画像が蓄積されていってしまうんです!

挿入される画像が増えてくると、ページ表示のパフォーマンスが悪くなります。

なのでモーダルを閉じるたびに、挿入した画像を削除するのが賢明です。

前回挿入した画像が一瞬だけチラッと見えてしまう

ズーム用の画像を削除しなければ、
パフォーマンスの低下に加え、もう一つの不具合を引き起こします。

どんな不具合か?

モーダルで画像をズームしようとすると、
前回挿入した画像が「チラ見」してしまう
んです。

1枚目では起こらないのですが、2枚目以降で「チラ見」が発生します。

この不具合を解消するためにも、
モーダルを閉じた瞬間にズーム用の画像を削除する必要があるのです。

モーダルを閉じるケースは以下になります。

  • 閉じるボタンをクリックしたとき
  • オーバーレイをクリックしたとき

なのでこれらのタイミングで、ズーム用の画像を削除する処理を実行しましょう。

// ズーム用の画像を削除
//-------------------------------------------------------------
function removeOldImage() {
  var $overlay = $('.overlay'),
      $modalClose = $('.modal-close');
  
  //モーダルの×ボタンをクリックしたときの挙動
  $modalClose.on('click', function(){
    removeImg();
  });
  
  //オーバーレイ領域をクリックしたときの挙動
  $overlay.on('click', function(){
    removeImg();
  });
  
  //ズーム用の画像を削除
  function removeImg() {
    var $zoomImg = $('.modal-wrap').find('.img-area').find('.zoomImg');
    $zoomImg.remove();
  }
}

完成形のDemo

See the Pen jQuery Zoom modal switch by さおさん (@saio-th) on CodePen.

長かったですが、これで一通りの流れが完了しました!
お疲れさまでした!

【まとめ】jQuery Zoomの使い方

モーダルを使わない場合はプログラムを1行追加するだけなので、とてもカンタンにズーム機能を利用することができます。
プラグインの作者様には感謝感謝です。

ただモーダル内でjQuery Zoomを使う場合は注意が必要でしたね。

  • モーダルで使用する場合は、モーダルを開くタイミングでzoomメソッドを実行する
  • モーダルで使用する場合は、モーダルを閉じるタイミングでズーム用の画像を削除する

これらのポイントを押さえておけば、
迷ったときも自分の力で解決できるでしょう!

以上です。
少しでもお役に立てたら嬉しいです。

【参考サイト】

Share

Comments

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。

CAPTCHA