$(function () {
/*
* ギャラリー
*/
//繰り返し処理ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
$('#gallery').each(function () {
var $container = $(this), //jquery変数
$loadMoreButton = $('#load-more'), // 追加ボタン
$filter = $('#gallery-filter'), // フィルタリングのフォーム
addItemCount = 16, // 一度に表示するアイテム数
addedd = 0, // 表示済みのアイテム数
allData = [], // すべての JSON データ
filteredData = []; // フィルタリングされた JSON データ
//masonryはサムネイルをタイル状に整列される
$container.masonry({
columnWidth: 230, //カラムの幅
gutter: 10, //カラム間の隙間
itemSelector: '.gallery-item' //並べる対象を指定している
});
// $.getJSON()メソッドは指定のURLからJSONデータを受け取って、処理する。
$.getJSON('./data/content.json', initGallery);
// ギャラリーを初期化する ---------------------------- 関数A
function initGallery (data) {
// 取得した JSON データを格納
allData = data;
// 最初の状態ではフィルタリングせず、そのまま全データを渡す
filteredData = allData;
// 最初のアイテムを表示
addItems();
// loadMoreボタンがクリックされたら追加で表示
$loadMoreButton.on('click', addItems);
// フィルターのラジオボタンが変更されたらフィルタリングを実行
$filter.on('change', 'input[type="radio"]', filterItems);
}
// アイテムを生成しドキュメントに挿入する-------------関数B
function addItems (filter) {
// 空の配列を用意する
var elements = [],
// 追加するデータの配列
/*filteredDataのデータ:addedd~addedd + addItemCount番目の手前のデータを抽出し、
配列slicedDataに入れる*/
slicedData = filteredData.slice(addedd, addedd + addItemCount);
// slicedData の要素ごとに DOM 要素を生成
$.each(slicedData, function (i, item) {
//変数
var itemHTML =
'<li class="gallery-item is-loading">' +
'<a href="' + item.images.large + '">' +
'<img src="' + item.images.thumb + '" alt="">' +
'<span class="caption">' +
'<span class="inner">' +
'<b class="title">' + item.title + '</b>' +
'<time class="date" datatime="' + item.date + '">' +
//replace('置換したい文字列','置換後の文字列')
item.date.replace(/-0?/g, '/') +
'</time>' +
'</span>' +
'</span>' +
'</a>' +
'</li>';
/*$(itemHTML)で、itemHTML から jQuery オブジェクトを生成し、get(0)で
<div>...</div>などの最初のDOM要素を取得し、push()で,elements配列に追加する。*/
elements.push($(itemHTML).get(0));
});
// DOM 要素の配列をコンテナーに挿入し、Masonry レイアウトを実行
/*
指定した要素をコンテナ($container)に追加し、すべて読み込まれたことを検知してから、
コールバック関数(function () { ... })を実行します。
*/
$container.append(elements).imagesLoaded(function () {
//読み込みを終了したら、is-loadingクラスを削除する
$(elements).removeClass('is-loading');
//新しい要素を、組み込んだ事をMasonryに通知し、グリッド状に並べる。
$container.masonry('appended', elements);
// #gallery-filterが有ったなら、再配置する
if (filter) {
$container.masonry();
}
});
// モーダルウィンドウ機能- - - - - - - - - - - - - - - - - - - - - - 新規追加
// リンクに Colorbox を設定
/*jQuery用のプラグインで、画像や動画、HTMLコンテンツなどを「モーダルウィンドウ(
子ウインドウ)」としてポップアップ表示できる機能を持つ*/
$container.find('a').colorbox({
maxWidth: '970px', //幅
maxHeight: '95%', //高
title: function () { //タイトル=コールバック関数
return $(this).find('.inner').html();
}
});
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// 追加済みアイテム数の更新
//変数addeddに配列slicedDataの「要素数+1」を入れる
addedd += slicedData.length;
// JSON データがすべて追加し終わっていたら追加ボタンを消す
if (addedd
$loadMoreButton.show(); //loadMoreボタンを表示する
} else {
$loadMoreButton.hide(); //loadMoreボタンを非表示にする
}
}
// アイテムをフィルタリングする----------------------関数c
function filterItems () {
var key = $(this).val(), // チェックされたラジオボタンの value
/*
* MasonryのgetItemElementsメソッドは、Masonryが適用されているグリッドコンテナ($container)から
*、指定された全ての子要素(DOM要素(divやliなど))を、配列として取得し、masonryItemsに格納する
*/
masonryItems = $container.masonry('getItemElements');
//コンテナ要素から、指定したアイテム(masonryItems)をMasonryのレイアウトから削除
$container.masonry('remove', masonryItems);
// フィルタリング済みアイテムのデータをリセットと
filteredData = [];
// 追加済みアイテム数をリセット
addedd = 0;
if (key === 'all') {
// all がクリックされた場合、すべての JSON データを格納
filteredData = allData;
} else {
// all 以外の場合、キーと一致するデータを抽出
/*
*jQuery のユーティリティ関数:$.grepは、allData 配列から
*item.カテゴリー が key と等しいものだけを抽出して、新しい配列 filteredDataに入れる
*/
filteredData = $.grep(allData, function (item) {
return item.category === key;
});
}
// アイテムを追加
addItems(true); //trueなら「すべてのアイテムを追加」
}
});
// jQuery UI Button------------------------------------------------------------
/* このコードは、jQuery UIのbuttonウィジェットを使って、
*filter-formクラス内のinput[type="radio"](ラジオボタン)をカスタマイズし、
*「icon-radio」というアイコンを付けてボタン化するものです
*/
$('.filter-form input[type="radio"]').button({
icons: {
//ボタンのprimary(左側)に「icon-radio」という名前のアイコンを表示します
primary: 'icon-radio'
}
});
/*
*-------------------------------------------------------------------
*Resize page header(スクロール中、ヘッダーサイズを変更する)
*page-header クラス内にある。すべての要素を対象にループ処理
*-------------------------------------------------------------------
*/
$('.page-header').each(function () {
//初期値の取得
//クラスpage-headerの 要素をjQueryオブジェクト化
var $header = $(this),
//要素自体の高さ + 上下のpadding値 + borderの値
headerHeight = $header.outerHeight(),
/*
*Jqueryのcss()メソッドは、セレクタ($header)のCSSの「padding-top」プロパティ値(32Ppx)を
*取得し、parseInt((),10 ) で,PX値を整数に直して、headerPaddingTopに入れる。
*/
headerPaddingTop = parseInt($header.css('paddingTop'), 10),
/*
*Jqueryのcss()メソッドは、セレクタのCSSの「padding-bottom」プロパティ値(32Ppx)を
*取得し、parseInt((),10 ) で,PX値を整数に直して、headerPaddingBottomに入れる。
*/
headerPaddingBottom = parseInt($header.css('paddingBottom'), 10);
/*
*ウィンドウがスクロールされるたびにスクロールイベントを発生しなさい。ただし、スクロール処理を
*1000/60 ミリ秒(約16.67ms)に1回、実行するようにする。
*/
$(window).on('scroll', $.throttle(1000 / 60, function () {
//現在のスクロール位置を「取得」し、変数scrollに入れる。
var scroll = $(this).scrollTop(),
//styles という変数に、空のオブジェクトを代入する。
styles = {};
//スクロール位置が0より大きい
if (scroll > 0) {
//スクロール位置がヘッダーの値より小さい
if (scroll
//paddingTop および paddingBottom の値をスクロール位置に応じて減少させる。
styles = {
paddingTop: headerPaddingTop - scroll / 2,
paddingBottom: headerPaddingBottom - scroll / 2
};
} else {
//スクロールが headerHeight 以上になったら、padding を 0 にしてヘッダーの高さを最小限にする。
styles = {
paddingTop: 0,
paddingBottom: 0
};
}
} else {
//スクロールが headerHeight 以上になったら、padding を 0 にしてヘッダーの高さを最小限にする
styles = {
paddingTop: '',
paddingBottom: ''
}
}
//styles を $header に適用して、パディングのサイズを変更する。
$header.css(styles);
}));
});
});
【CSSフォルダー】
main.cssファイルにコードを書く
@charset "UTF-8";
/* Base */
html {
"Helvetica Neue", "Arial", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
font-size: 14px;
/*行の高さ*/
line-height: 1.5;
}
body {
background-color: rgb(245, 245, 245);
color: rgb(0, 0, 0);
}
h1 {
font-size: 100%;
margin: 0;
}
img {
/*垂直方向の中央寄せ*/
vertical-align: middle;
}
/*疑似クラス 前後に空白を入れる*/
.clearfix:before, .clearfix:after {
content: " ";
/*要素を横に並べる*/
display: table;
}
.clearfix:after {
clear: both;
}
/* Page header */
.page-header {
background-color: rgb(255, 255, 255);
border-bottom: 1px solid rgb(230, 230, 230);
padding: 32px 0;
/*要素位置を固定する*/
position: fixed;
width: 100%;
z-index: 10;
}
.page-header > .inner {
width: 950px;
padding: 8px 10px;
margin: auto;
}
site-logo {
float: left;
line-height: 1;
}
/* Page main */
.page-main {
margin: auto;
padding: 103px 10px;
width: 950px;
}
/*!
* Gallery
*/
.gallery {
margin: 0;
padding: 0;
}
.gallery-item {
list-style: none;
margin-top: 10px;
}
.gallery-item.is-loading {
/*透明度(透過度)を指定するプロパティ*/
opacity: 0;
}
.gallery-item a {
display: block;
}
.gallery-item .caption {
display: none;
}
/* フィルター */
.filter-form {
float: right;
}
.filter-form label {
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-left: 1em;
padding: 0 0.25em;
/*テキストを選択できない様する*/
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.filter-form label.ui-state-focus {
outline: 1px dotted;
}
.filter-form label .ui-icon {
background: url(../img/sprites.png) no-repeat 0 0;
display: inline-block;
height: 17px;
margin-right: 0.5em;
margin-top: 2px;
width: 17px;
vertical-align: top;
}
.filter-form label.ui-state-active .ui-icon {
background-position: -20px 0;
}
/* 追加読み込みボタン */
.load-more {
background-color: rgb(255, 255, 255);
border: 1px solid rgb(230, 230, 230);
display: block;
padding: 1em 0;
width: 100%;
margin-top: 10px;
}
/* jQuery UI helper */
.ui-helper-hidden-accessible {
border: 0;
/*要素を切り抜いて可視化する範囲を指定*/
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}