Javascriptのスライダーライブラリ「Swiper.js」を使って以下の要件を満たすスライドショーを作る方法をご紹介します。
- スライドショーとは別のセクションのカードアイテムをクリックしたときにモーダルを表示
- モーダル内でスライドショー展開
- 表示するスライドは、クリックされたカードアイテムの番号と連動させる
一度も上記の内容で実装したことがない方は、要件を見ただけで「うっ…」となってしまうでしょう。かくいうぼくもそうでした笑
しかし、Swiperで用意されているオプションを使えばなんてことないのでご安心を!Web制作案件をやっていたら必ず立ち向わざるをえないものなのでぜひ覚えましょう〜
完成イメージ
百聞は一見に如かず!
この記事で紹介するコードをコピペして実装できるスライドショーはこちらです。
ポチポチ押してご自身の実装したいものにイメージが近いか確かめてみてください。
See the Pen Swiperとモーダル連動 by 石森裕也 (@yuyaphotograph) on CodePen.
サンプルコード
完成イメージを実現するサンプルコードがこちら!
HTML
functions.php
<!-- カードセクション -->
<div class="Card">
<div class="Card-Item">カード1</div>
<div class="Card-Item">カード2</div>
<div class="Card-Item">カード3</div>
</div>
<!-- モーダルとスライドショー -->
<div class="ModalLayer">
<div class="ModalLayer-Mask"></div>
<div class="ModalLayer-Inner">
<div class="ModalSection">
<div class="Modal">
<div class="Modal-Inner">
<!-- Swiper -->
<div class="swiper-container Modal-Inner-Card">
<div class="swiper-wrapper Modal-Inner-Card-Wrapper">
<!-- item -->
<div class="swiper-slide Modal-Inner-Card-Wrapper-Slide">
<div class="Modal-Inner-Card-Wrapper-Slide-Item">
<div class="Modal-Inner-Card-Wrapper-Slide-Item-Box">
<p class="Modal-Inner-Card-Wrapper-Slide-Item-Box-Text">カード1の内容</p>
</div>
</div>
</div>
<!-- item -->
<div class="swiper-slide Modal-Inner-Card-Wrapper-Slide">
<div class="Modal-Inner-Card-Wrapper-Slide-Item">
<div class="Modal-Inner-Card-Wrapper-Slide-Item-Box">
<p class="Modal-Inner-Card-Wrapper-Slide-Item-Box-Text">カード2の内容</p>
</div>
</div>
</div>
<!-- item -->
<div class="swiper-slide Modal-Inner-Card-Wrapper-Slide">
<div class="Modal-Inner-Card-Wrapper-Slide-Item">
<div class="Modal-Inner-Card-Wrapper-Slide-Item-Box">
<p class="Modal-Inner-Card-Wrapper-Slide-Item-Box-Text">カード3の内容</p>
</div>
</div>
</div>
</div>
</div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<div class="Modal-Inner-Btn JS_Click_CloseModal_Trigger">
☓
</div>
</div>
</div>
</div>
</div>
</div>
CSS
僕が普段使っているのはStylusですが、普通のCSSをお使いの方も多いと思うので両者載せておきます。
普通のCSSver
/* ---------------------------- */
/* --- カードセクション --- */
/* ---------------------------- */
.Card {
margin-top: 24px;
width: 100%;
display: flex;
flex-wrap: wrap;
}
.Card-Item {
width: calc((100% - 56px) / 3);
background: #eee;
cursor: pointer;
}
.Card-Item:not(:nth-child(3n-2)) {
margin-left: 28px;
}
/* ---------------------------- */
/* --- ModalSection --- */
/* ---------------------------- */
.ModalLayer {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
transition: opacity 0.65s;
pointer-events: none;
opacity: 0;
z-index: 10000;
}
.ModalLayer.isShow {
transition: opacity 0.65s;
pointer-events: auto;
opacity: 1;
}
.ModalLayer-Mask {
position: absolute;
background: rgba(0,0,0,0.5);
width: 100%;
height: 100vh;
}
.ModalLayer-Inner {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
max-width: 600px;
transform: translate(-50%, -50%);
}
.Modal-Inner-Btn {
position: absolute;
top: -35px;
right: -35px;
width: 70px;
color: #fff;
z-index: 10;
cursor: pointer;
}
.Modal-Inner-Card {
width: 100%;
}
.Modal-Inner-Card-Wrapper {
display: flex;
}
.Modal-Inner-Card-Wrapper-Slide {
width: 100% !important;
height: auto;
}
.Modal-Inner-Card-Wrapper-Slide-Item {
padding-top: 50px;
padding-bottom: 50px;
width: 100%;
height: 100%;
background: #059bcc;
}
.Modal-Inner-Card-Wrapper-Slide-Item-Box {
position: relative;
margin-left: auto;
margin-right: auto;
width: 78.37%;
}
.Modal-Inner-Card-Wrapper-Slide-Item-Box-Text {
color: #fff;
}
Stylus
/* ---------------------------- */
/* --- カードセクション --- */
/* ---------------------------- */
.Card
margin-top 24px
width: 100%
display: flex
flex-wrap: wrap
&-Item
width: calc((100% - 56px) / 3)
background: #eee;
cursor: pointer
&:not(:nth-child(3n-2))
margin-left: 28px
/* ---------------------------- */
/* --- ModalSection --- */
/* ---------------------------- */
.ModalLayer
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
transition: opacity 0.65s;
pointer-events: none;
opacity: 0;
z-index: 10000;
.ModalLayer.isShow
transition: opacity 0.65s;
pointer-events: auto;
opacity: 1;
.ModalLayer-Mask
position: absolute;
background: rgba(0,0,0,0.5);
width: 100%;
height: 100vh;
.ModalLayer-Inner
position: absolute;
top: 50%;
left: 50%;
width: 100%;
max-width: 600px;
transform: translate(-50%, -50%);
// Swiper部分
.Modal
&-Inner
&-Btn
position: absolute;
top: -35px
right: -35px
width: 70px
color: #fff
z-index: 10
cursor: pointer
&-Card
width 100%
&-Wrapper
display: flex;
&-Slide
width 100%!important
height: auto
&-Item
padding-top: 50px
padding-bottom: 50px
width 100%
height: 100%
background: #059bcc
&-Box
position: relative
margin-left: auto;
margin-right: auto;
width: 78.37%
&-Text
color: #fff
Javascript
JS
$(function(){
var swiper = new Swiper('.swiper-container', {
loop: true,
slidesPerView: 'auto',
centeredSlides: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
}
});
// モーダル開く
$('.Card-Item').on('click', function(){
var index = $(this).index();//クリックした要素のインデックスを取得
swiper.slideTo(index);//指定のスライドを呼び出し
$('.ModalLayer').addClass('isShow');
});
$('.ModalLayer-Mask').on('click', function(){
$('.ModalLayer').removeClass('isShow');
});
$('.JS_Click_CloseModal_Trigger').on('click', function(){
$('.ModalLayer').removeClass('isShow');
});
});
次はこの記事!
Swiper.jsカスタマイズに役立つ記事まとめ