とても便利なWP REST APIに、JavaScriptライブラリ「Swiper.js」を絡めて記事一覧をスライダーにしてみます。
コード量は多いですが、分解していくと簡単です。これらを実際のサンプルと絡めて解説していきます。
SwiperとWP REST API
まずはじめにスライダーの「Swiper」と、記事情報を連携させる「WP REST API」を中心に解説していきます。
Swiper
Swiperは、スライダー・カルーセルUIの超定番とも言えるJavaScriptのライブラリです。ネイティブなJavaScriptなので、jQuery不要でスライダーを実装できるのが大きいメリットです。
カスタマイズが容易で、スマホのスワイプにも対応しているので非常に便利なライブラリです。
以下の記事では、このSwiper.jsについて解説していますので詳細は以下の記事もご覧ください。
スライダーの超定番ライブラリSwiper.jsの基本と使い方WP REST API
WP REST APIは、WordPressの外部からそのWordPressにアクセスすることができるAPIです。
例えば「A」というWordPressでできたサイトの記事を、「B」のサイトやページで表示する場合に使います。なお、この「B」のサイトはWordPressじゃなくてもOKです。
このように、WP REST APIはいろんな用途に使える為、SPA(シングルページアプリケーション)で使われたりします。
記事一覧をスライダー表示にしたサンプル
それではサンプルです。
APIで記事一覧を生成して、Swiper でスライダーを作ったサンプルです。
スライダーの使用や見た目はSwiperのオプションでいじります。その辺も含め解説していきます。
サンプルのコード
サンプルのコードは、HTML・CSS・JavaScriptの3種です。順に解説していきます。
HTML
HTMLでは、まずはじめにSwiper本体を読み込ませる必要があるので、以下のコードをHTMLの <head>〜</head>
の中に記述しましょう。
<link
rel="stylesheet"
href="https://unpkg.com/swiper@7/swiper-bundle.min.css"
/>
<script src="https://unpkg.com/swiper@7/swiper-bundle.min.js"></script>
上記は記述するだけでOKなCDNでの読み込みの場合です。同じサーバーに置いたファイルとして使う場合は、ダウンロードして設置したパスを記述しましょう。
そして次に、スライダーを設置したい場所に以下のHTMLを記述します。
<div class="sliderWrapper">
<div class="sample-swiper carousel">
<div class="swiper-container">
<!-- Additional required wrapper -->
<div id="viewPosts" class="swiper-wrapper"></div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
<!-- Slider main container -->
</div>
</div>
これらの設置が完了したら、HTMLの記述は終了です。
JavaScript
JavaScriptで書くコードは多めです。特に読み込ませていく順番が重要なので、それぞれ適切な場所に書き込んでいきましょう。
WP REST APIのコードは、HTMLの head
の中で読み込ませて早めに読み込ませます。以下のコードは、WP REST APIのコードで、HTMLのヘッダーで読み込ませるように記述しましょう。
const getPosts = "https://dubdesign.net/domain/wp-json/wp/v2/posts?_embed&per_page=10"
fetch(getPosts).then(
response => {
return response.json(); // get JSON data$
}).then(data => {
for (let i = 0; i < data.length; i++) {
var date2 = new Date(data[i].date);
var year = date2.getFullYear();
var month = date2.getMonth() + 1;
var day = date2.getDate();
viewPosts.innerHTML += '<div class="swiper-slide">'
+ '<a href="' + data[i].link + '" class="linkID_' + data[i].id +'">'
+ '<img src="' + data[i]._embedded["wp:featuredmedia"][0].source_url + '" alt="' + data[i].title.rendered +'">'
+ '<time class="postTime dfont" itemprop="datePublished" datetime="' + data[i].date + '">' + year + '年' + month + '月' + day + '日' + '</time>'
+ '<p class="postTitle">' + data[i].title.rendered + '</p>'
+ '</a>'
+ '</div>' // end content
}
}).catch(err => {
// Do something with error here
console.log('Error: ' + err)
})
読み込みの順番が違うと、画像が遅滞読み込みで表示されなかったりするので順番は注意しましょう。
次に読み込むのは、Swiperの仕様や動作を作るオプションと、スライダーの中の要素の高さを揃えるJavaScriptのコードを記述します。
const swiper = new Swiper(".swiper-container", {
// ドットインジケーターの表示
pagination: {
el: ".swiper-pagination",
},
// 前後スライドボタンを表示
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
loop: true, // ループの有効化
slidesPerView: 1.2, // 表示するスライドの枚数
centeredSlides : true, // スライドを中央揃えを有効化
effect: "coverflow",
coverflowEffect: {
rotate: 0, // 回転角度
stretch: 50, // 間隔(px単位)
depth: 200, // pxで奥行き
modifier: 1, // 角度
slideShadows : true, // 先頭のbox-shadow
},
});
const autoHeight = () => {
let elem = document.getElementById('viewPosts');
let elemChildren = elem.children;
let elemMaxHeight = 0;
let elemArray = new Array;
Array.prototype.forEach.call(elemChildren, function(elemChild) {
elemChild.style.height = '';
elemArray.push(elemChild.clientHeight);
});
elemMaxHeight = Math.max.apply(null, elemArray);
Array.prototype.forEach.call(elemChildren, function(elemChild) {
elemChild.style.height = elemMaxHeight + 'px';
});
}
window.addEventListener('load', autoHeight);
window.addEventListener('resize', autoHeight);
このコードは、<body>〜</body>
のクロージングタグ付近に記述するようにします。
スライダーの中身の要素を揃えなくても良い場合は、const autoHeight〜
以降の部分を削除ください。
CSS
CSSは、スライダー内のレイアウトやページネイション等の基本の部分は本体のCSSで読み込むので、スライダーの微調整と、スライダーの中身と記述量はそこまで多くありません。
.carousel {
overflow: hidden;
box-shadow: none;
padding-top: 10px;
padding-bottom: 30px;
}
.swiper-pagination.swiper-pagination-bullets.swiper-pagination-horizontal {
bottom: -5px;
position: relative;
}
.swiper-slide.swiper-slide-visible.swiper-slide-prev, .swiper-slide.swiper-slide-visible.swiper-slide-next {
pointer-events: none;
}
.swiper-slide a {
background: #fff;
display: flex;
margin: 0px 30px;
box-shadow: 0 0 3px 0 rgb(0 0 0 / 12%), 0 2px 3px 0 rgb(0 0 0 / 22%);
cursor: pointer;
transition: 0.2s ease-in-out;
border-radius: 3px;
flex-direction: column;
height: 100%;
text-decoration: none;
}
.swiper-slide a:hover {
box-shadow: 0 15px 30px -5px rgb(0 0 0 / 15%), 0 0 5px rgb(0 0 0 / 10%);
transform: translateY(-4px);
}
.swiper-slide a img {
margin-bottom: 15px;
object-fit: cover;
height: 300px;
border-radius: 3px 3px 0 0;
}
p.postTitle {
padding: 0px 20px 0;
font-size: 18px;
line-height: 1.56;
color: #555;
font-weight: 600;
margin-bottom: 1.2rem;
}
time.postTime {
display: block;
margin: 0 0 3px;
color: #b5b5b5;
font-size: 0.9rem;
font-weight: bold;
padding: 0 20px;
position: relative;
}
time.postTime:before {
content: "\f017";
font-family: "Font Awesome 5 Free";
font-weight: 900;
padding-right: 5px;
font-size: 0.85rem;
opacity: 0.6;
vertical-align: bottom;
}
@media screen and (max-width: 767px) {
/* (ここにモバイル用スタイルを記述) */
.swiper-slide a img {
object-fit: none;
height: auto;
}
p.postTitle {
font-size: 16px;
}
}