こんにちは、エムケーワイです。
今回はギャラリーページの第2弾です。
第1弾ではギャラリーの画像は20種類でしたが、第2弾では89種類に増やします。89種類の画像を一気に表示しようとするとロードにかかる時間が長くなるので、まず16種類表示し、その後「Load More」ボタンがクリックされる毎に16種類ずつ追加表示して行きます。そして全画像が表示されたら「Load More」ボタンを消去します。
では、早速結果を見ていただきます。
第1弾に対する主な追加・修正ポイントは下記になります。
- jQueryの関数createHTML()の処理の修正。表示対象となるJSONデータのみを取得してHTMLコードを生成するようにします。
- 「Load More」ボタンクリック時の処理の追加。
では、実現方法を説明して行きます。
1. HTMLコード
今回カスタムHTMLで記述したコードは下記の通りです。
第1弾のコードに「Load More」ボタン用のコードを追記しました。
<div class="mkyGalleryContainer">
<ul class="mkyGallery"></ul>
<button class="loadMore" id="loadMore">Load More</button>
</div>
2. JSONファイル
今回使用するJSONファイルは”galleryFull.json”というファイル名で、子テーマフォルダ(twentytwenty_ch)内のフォルダgalleryに置かれています。
第1弾で使用したgallery.jsonに対しデータ(配列の要素)を追加しただけで、各要素の構成は第1弾と同じです。
[
{
"title": "Night View",
"category": "HongKong",
"images": {
"thumb": "/wp-content/themes/twentytwenty_ch/gallery/images/thumb-H-8.jpg",
"large": "/wp-content/themes/twentytwenty_ch/gallery/images/large-H-8.jpg"
}
},
{
"title": "Victoria Harbor",
"category": "HongKong",
"images": {
"thumb": "/wp-content/themes/twentytwenty_ch/gallery/images/thumb-H-4.jpg",
"large": "/wp-content/themes/twentytwenty_ch/gallery/images/large-H-4.jpg"
}
},
{ ... }
]
今回追加した画像も全て私自身が撮影したものです。
3. JavaScriptライブラリの読み込み
当たり前ですが、第2弾でもJavaScriptライブラリImagesLoadedとMasonryを使用します。
第1弾と同じようにfunctions.phpで上記ライブラリの読み込み設定を行っています。
4. jQueryコード
今回作成したjQueryコードは下記になります。
第1弾のjQueryコードに対して追加・修正した部分をメインに説明します。
jQuery(function() {
jQuery('.mkyGallery').each(function() {
var _gallery = jQuery(this), // ギャラリーオブジェクト
_loadMoreButton = jQuery('#loadMore'), // 「Load More」ボタン
addImgCount = 16, // クリック毎に追加する画像数
imgCount = 0, // 現在の表示画像数
jsonData = [], // JSONデータ
galleryW = _gallery.width(), // ギャラリー領域の幅
imageW = 300, // 画像の幅
gutterW; // gutterの幅
// gutterの幅を算出
if (galleryW > 900) {
gutterW = Math.floor((galleryW - imageW * 3) / 2);
} else if (galleryW > 600) {
gutterW = galleryW - imageW * 2;
} else {
gutterW = galleryW - imageW;
}
// Masonry初期設定
_gallery.masonry({
columnWidth: 300,
gutter: gutterW,
itemSelector: '.mkyGalleryItem'
});
// JSONデータを取得し、ギャラリーを生成する
jQuery.getJSON('/wp-content/themes/twentytwenty_ch/gallery/galleryFull.json', function(data) {
// 取得した JSON データを格納
jsonData = data;
// ギャラリーのHTMLコードを生成し、画像を表示する
createHTML();
// Load Moreボタンクリックで画像を追加
_loadMoreButton.on('click', createHTML);
});
// HTMLコードを生成しギャラリーを表示する
function createHTML() {
var elements = [],
slicedData = jsonData.slice(imgCount, imgCount + addImgCount);
// JSON配列内の要素毎に処理する
jQuery.each(slicedData, function (i, item) {
// HTMLコード(文字列)を生成する
var htmlCode =
'<li class="mkyGalleryItem onLoading">' +
'<a class= "mkyJsModalOpen" href="' + item.images.large + '">' +
'<img src="' + item.images.thumb + '" alt="">' +
'</a>' +
'<div class="mkyModal mkyJsModal" style="display: none;">' +
'<div class="mkyModalBG"></div>' +
'<div class="mkyModalContent">' +
'<figure>' +
'<img src="' + item.images.large + '" alt="">' +
'<span class="caption">' +
'<b class="title">' + item.title + '</b>' +
'</span>' +
'<button class="mkyJsModalClose">×</button>' +
'</figure>' +
'</div>' +
'</div>' +
'</li>';
// HTMLコード(文字列)をDOM要素化し、配列に追加
elements.push(jQuery(htmlCode).get(0));
});
// DOM要素の配列をギャラリーに挿入し、Masonryを実行
_gallery
.append(elements)
.imagesLoaded(function() {
jQuery(elements).removeClass('onLoading');
_gallery.masonry('appended', elements);
});
// 現在の表示画像数を更新
imgCount += slicedData.length;
// 全画像が表示されたらLoadMoreボタンを消去
if (imgCount < jsonData.length) {
_loadMoreButton.show();
} else {
_loadMoreButton.hide();
}
// 画像のモーダル表示
jQuery('.mkyGalleryItem').on('click',function(){
jQuery(this).find('.mkyJsModal').fadeIn();
return false;
});
jQuery('.mkyJsModalClose').on('click',function(){
jQuery(this).parents('.mkyJsModal').fadeOut();
return false;
});
}
});
});
4-1. 全体の流れ
全体の流れは第1弾とほぼ同じですが、下記の処理が追加されています。
- 「Load More」ボタンクリック時の処理
- JSONデータから表示対象となるデータのみを取得する処理
- 現在の表示画像数を更新する処理
- 全画像が表示されたら「Load More」ボタンを消去する処理
4-2. 変数の宣言、初期化
第1弾に対し下記の変数が追加されています。
変数 | 意味 |
_loadMoreButton | 「Load More」ボタンオブジェクト |
addImgCount | クリック毎に追加する画像数(16) |
imgCount | 現在の表示画像数 初期値として0を代入 |
4-3. Masonryの初期設定
第1弾と同じです。
4-4. JSONデータの取得とギャラリー生成
getJSON()メソッドで読み込むJSONファイル名が異なりますが、関数createHTML()を呼び出すまでの処理は第1弾と同じです。
createHTML()呼び出し後に、「Load More」ボタンクリック時の処理を追加しています。この時実行する処理は、最初の16種類の画像を表示する際と同じで、HTMLコードの生成と画像の配置・表示です。これらの処理は関数createHTML()にまとめられているので、実際の処理はcreateHTML()を呼び出すだけとなります。
jQuery.getJSON('/wp-content/themes/twentytwenty_ch/gallery/galleryFull.json', function(data) {
// 取得した JSON データを格納
jsonData = data;
// ギャラリーのHTMLコードを生成し、画像を表示する
createHTML();
// Load Moreボタンクリックで画像を追加
_loadMoreButton.on('click', createHTML);
});
今回「Load More」ボタンクリック時の処理をgetJSON()メソッドの第2引数の関数内に記述しましたが、getJSON()メソッドの後ろに記述しても動作します。
4-5. HTMLコードの生成と画像の配置・表示
本処理は第1弾の時点で関数createHTML()にまとめられています。関数createHTML()は、「Load More」ボタンクリック時にも呼び出されます。
4-5-1. HTMLコードの生成
HTMLコード作成の前に、slice()メソッドを使ってjsonDataから表示対象となる要素のみを取得し、変数slicedDataに代入してます。
第2弾では、slicedData内のデータに基づいてHTMLコードを生成しますが、HTMLコード生成処理、HTMLコード(文字列)をDOM要素化して配列elementsに追加する処理は第1弾と同じです。
var slicedData = jsonData.slice(imgCount, imgCount + addImgCount);
// JSON配列内の要素毎に処理する
jQuery.each(slicedData, function (i, item) {
...
});
galleryFull.jsonファイルの読み込みは、HTMLコード生成の際に毎回行われるわけではありません。起動時に1度だけ行われ、全データが変数jsonDataに格納されます。
変数slicedDataには、変数jsonDataからslice()メソッドで切り出されたデータが代入されます。
4-5-2. 画像の配置、表示
第1弾と同じです。
4-5-3. 現在の表示画像数更新
変数imgCountにslicedData.Lengthを加算します。
imgCount += slicedData.length;
4-5-4. 「Load More」ボタンの消去
jsonData内の全画像が表示されたら(imgCount >= jsonData.length)「Load More」ボタンを消去します。
if (imgCount >= jsonData.length) {
_loadMoreButton.hide();
}
4-5-5. 画像のモーダル表示
第1弾と同じです。
5. CSS設定
/*
* 「Load More」ボタン
*/
.loadMore {
background-color: crimson;
border: 2px solid crimson;
border-radius: 5px;
color: white;
display: block;
padding: 1rem 0;
width: 60%;
margin-top: 30px;
margin-left: auto;
margin-right: auto;
}
.loadMore:hover {
background-color: white;
color: crimson;
}
「Load More」ボタン向けの設定を追加しました。特に説明は不要ですね。
マウスホバー時に背景色と文字色を反転させています。
いかがでしたでしょうか?
今回はslice()メソッドを使って、配列内の指定範囲の要素を取得する、というのが肝だったかなと思います。後は、第1弾の処理をほぼそのまま使うことができました(今回説明を省略した部分については第1弾の投稿をご参照ください)。
第3弾ではカテゴリー別に表示する機能を追加する予定です。画像の種類が16より多いカテゴリーでは、一度に全画像を表示せず、「Load More」ボタンで追加して行きます。
第3弾も出来るだけ早く備忘録を投稿できるよう頑張ります!
最後までお読みいただきありがとうございました。