🦍

画像クリックでのモーダル表示の実装

2024/10/17に公開

とあるWEB制作で画像をスライダーで流れるようにしつつ、画像をクリックした際にはモーダルで画像と説明文を表示させたい。という要望があったので備忘録として残しておきます。

ちなみに、ここでのWEBサイトはwordpressで構築を行なっています。ですが、基本的にはhtml/cssで作ったページに対して、jqueryとcssだけでうまく工夫をしながらアニメーションなどの動きを作成しています。

reactなどを用いてWEB制作を行えばもっと楽に動きの多いサイトを作ることができるとは思いますが、あくまで初心者やhtml/cssと少しのjsが理解できる人向けに作成しています。

概要

まずは完成イメージです。
行なっていることとしては、

  • 画像をフェードインでランダムに表示するスライドを3つ用意する
  • 画像をクリックするとその画像に関する詳細を記載したモダールが表示される

※初期状態だと少し見にくいので、0.5xにした方が見やすいと思います

実現するのに使うもの

使っているのは冒頭でも記載した通り、html/cssとjavascript(jquery)です。

その上で、よくあるアニメーションを組み合わせています。それぞれ分解してみると

  • 画像のフェードイン部分についてはslickで実現
    • 3箇所に同じように作る
    • 画像が切り替わるタイミングがずれるように調整する
  • 画像クリックでモーダルが表示されるようにする
    • クリックする画像によって特定の内容が表示されるように調整する

と言いた感じでしょうか。それぞれ見ていきましょう。

html部分

htmlの記述

<ul class="img_list img_wrap" randomPh="3">
   <li class="item slideshow img_box">
       <div class="img js_modal_open" data-type="a_list-1">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29386534_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-2">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29840337_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-3">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29915166_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-4">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/30515501_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-5">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/31016427_s.jpg" alt="">
       </div>
   </li>
   <li class="item slideshow img_box">
       <div class="img js_modal_open" data-type="a_list-5">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/31016427_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-1">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29386534_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-3">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29915166_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-2">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29840337_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-4">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/30515501_s.jpg" alt="">
       </div>
   </li>
   <li class="item slideshow img_box">
       <div class="img js_modal_open" data-type="a_list-3">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29915166_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-2">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29840337_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-5">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/31016427_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-4">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/30515501_s.jpg" alt="">
       </div>
       <div class="img js_modal_open" data-type="a_list-1">
           <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29386534_s.jpg" alt="">
       </div>
   </li>
</ul>

<div class="js_modal_area">
   <div class="modal js_modal js_modal_box1">
       <div class="modal__bg js_modal_close"></div>

       <!-- これでモーダルの中身のwrap -->
       <!-- 親もjs_modal_areeaをjsでfadeinさせつつ、idで画像に該当するいずれかのwrapにクラス付与で表示させる。それ以外/デフォルトはdisplay:none -->
       <div class="js_modal_content modal__content" id="a_list-1">
           <span class="js_modal_close" href="">×</span>
           <div class="img_box">
               <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29386534_s.jpg" alt="">
           </div>
           <div class="ttl_area">
               <p class="head">見出し</p>
           </div>
           <p class="text">ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。</p>
       </div>
        <!--/ これでモーダルの中身のwrap -->

       <div class="js_modal_content modal__content" id="a_list-2">
           <span class="js_modal_close" href="">×</span>
           <div class="img_box">
               <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29840337_s.jpg" alt="">
           </div>
           <div class="ttl_area">
               <p class="head">見出し</p>
           </div>
           <p class="text">ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。</p>
       </div>

       <div class="js_modal_content modal__content" id="a_list-3">
           <span class="js_modal_close" href="">×</span>
           <div class="img_box">
               <img src="http://fnnyxe.com/wp-content/uploads/2024/10/29915166_s.jpg" alt="">
           </div>
           <div class="ttl_area">
               <p class="head">見出し</p>
           </div>
           <p class="text">ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。</p>
       </div>

       <div class="js_modal_content modal__content" id="a_list-4">
           <span class="js_modal_close" href="">×</span>
           <div class="img_box">
               <img src="http://fnnyxe.com/wp-content/uploads/2024/10/30515501_s.jpg" alt="">
           </div>
           <div class="ttl_area">
               <p class="head">見出し</p>
           </div>
           <p class="text">ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。</p>
       </div>

       <div class="js_modal_content modal__content" id="a_list-5">
           <span class="js_modal_close" href="">×</span>
           <div class="img_box">
               <img src="http://fnnyxe.com/wp-content/uploads/2024/10/31016427_s.jpg" alt="">
           </div>
           <div class="ttl_area">
               <p class="head">見出し</p>
           </div>
           <p class="text">ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。</p>
       </div>
   </div>
</div>

↑がhtmlの全文です。

cssの部分

cssの記述
/* 画像を並べている部分のcss */
.img_wrap {
   display: flex;
   flex-wrap: wrap;
   max-width: 1000px;
   margin: auto;
   width: 80%;
}

.img_wrap .img_box {
   width: 31%;
   margin: 1%;
   position: relative;
   padding-bottom: 31%;
   cursor: pointer;
}

.img_wrap .img_box .img {
   position: absolute;
   width: 100%;
   padding-bottom: 100%;
}

.img_wrap .img_box .img img {
   position: absolute;
   object-fit: cover;
   width: 100%;
   height: 100%;
}

/* モーダル部分のデザイン */
.js_modal_area {
   display: none;
}

.js_modal_area .modal {
   position: fixed;
   width: 100%;
   height: 100vh;
   top: 0;
   left: 0;
   z-index: 10;
}

.modal__bg {
   position: relative;
   z-index: 1;
   background: #00000080;
   width: 100%;
   height: 100%;
}

.js_modal_area .modal .modal__content {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
   width: 80%;
   background: #fff;
   max-width: 800px;
   z-index: 9999;
   padding: 90px 30px;
   display: none;
}

.js_modal_area .modal .modal__content.active {
   display: block;
}

.js_modal_area .modal .modal__content .img_box {
   width: 80%;
   margin: 2% auto;
}

.js_modal_area .modal .modal__content p {
   width: 80%;
   margin: auto;
   margin-top: 12px;
   line-height: 1.4;
   font-size: 13px;
}

.js_modal_area .modal .js_modal_close {
   text-align: center;
   display: block;
   position: absolute;
   top: 10px;
   right: 15px;
   cursor: pointer;
   font-size: 30px;
   font-weight: 700;
}

↑がcssの全文です。

js(jquery)の部分

jqueryの記述
// モーダルの表示用
$(function() {
   $('.js_modal_open').on('click', function() {
       const id = $(this).attr('data-type');
       $('#' + id).addClass('active')
       $('.js_modal_area').fadeIn();
       return false;
   });
   $('.js_modal_close').on('click', function() {
       $('.js_modal_area').fadeOut();
       $('.js_modal_content'

       ).removeClass('active')
       return false;
   });
});

// 画像のスライダー用
// .img_listの配下にあるliに対して下のしarrの中のクラス名がページの読み込みでその都度ランダムで付与されます。
var arr = ['slideshow01', 'slideshow02', 'slideshow03'];
var a = arr.length;
while (a) {
   var j = Math.floor(Math.random() * a);
   var t = arr[--a];
   arr[a] = arr[j];
   arr[j] = t;
}
arr.forEach(function(value, index) {
   $('.slideshow').eq(index).addClass(value);
});

// それぞれの付与されたクラスに対してそ順番にフェードインフェードアウトを繰り返すjs処理
// これにより画像の表示を実現しています
$(function() {
   $('.slideshow01 .img:nth-child(n+2)').hide();
   setInterval(function() {
       $(".slideshow01 .img:first-child").fadeOut(2000);
       $(".slideshow01 .img:nth-child(2)").fadeIn(2000);
       $(".slideshow01 .img:first-child").appendTo(".slideshow01");
   }, 4000);

   $('.slideshow02 .img:nth-child(n+2)').hide();
   setInterval(function() {
       $(".slideshow02 .img:first-child").fadeOut(2000);
       $(".slideshow02 .img:nth-child(2)").fadeIn(2000);
       $(".slideshow02 .img:first-child").appendTo(".slideshow02");
   }, 5000);

   $('.slideshow03 .img:nth-child(n+2)').hide();
   setInterval(function() {
       $(".slideshow03 .img:first-child").fadeOut(2000);
       $(".slideshow03 .img:nth-child(2)").fadeIn(2000);
       $(".slideshow03 .img:first-child").appendTo(".slideshow03");
   }, 6000);

   $.fn.extend({
       randomPh: function(num) {
           return this.each(function() {
               var chn = $(this).children().hide().length;
               for (var i = 0; i < num && i < chn; i++) {
                   var r = parseInt(Math.random() * (chn - i)) + i;
                   $(this).children().eq(r).show().prependTo($(this));
               }
           });
       }
   });
   $("[randomPh]").each(function() {
       $(this).randomPh($(this).attr("randomPh"));
   });
});

↑がjsの全文です。

Discussion