カテゴリー
CSS HTML jQuery Webサイト作成

ギャラリーページ(2)

こんにちは、エムケーワイです。

今回はギャラリーページの第2弾です。

第1弾ではギャラリーの画像は20種類でしたが、第2弾では89種類に増やします。89種類の画像を一気に表示しようとするとロードにかかる時間が長くなるので、まず16種類表示し、その後「Load More」ボタンがクリックされる毎に16種類ずつ追加表示して行きます。そして全画像が表示されたら「Load More」ボタンを消去します。

では、早速結果を見ていただきます。

    第1弾に対する主な追加・修正ポイントは下記になります。

    1. jQueryの関数createHTML()の処理の修正。表示対象となるJSONデータのみを取得してHTMLコードを生成するようにします。
    2. 「Load More」ボタンクリック時の処理の追加。

    では、実現方法を説明して行きます。

    目次 [閉じる]
    1. HTMLコード
    2. JSONファイル
    3. JavaScriptライブラリの読み込み
    4. jQueryコード
    5. CSS設定

    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弾も出来るだけ早く備忘録を投稿できるよう頑張ります!

    最後までお読みいただきありがとうございました。