タイルのように可変グリッドレイアウトを自動で表示してくれる、超定番&超便利なjQueryプラグイン、「Masonry」。
しかし、この「Masonry」には残念なことにフィルター機能がありません。
フィルター機能とは、例えばショップサイトで画像付きの商品一覧ページをタイルレイアウトで表示している場合、商品の色や機能など、特徴ごとに商品リストをリアルタイムに並べ替えるようなことができるものです。
「Masonry」と同じように自動でグリッドレイアウトを表示して、フィルター機能も付いているプラグインで有名なものとしては、「isotope」というプラグインがありますが、こちらはGPLv3ライセンスの下で商用利用の場合は有料となってしまいます。
そこで、「Masonry」の唯一(?)の弱点であるフィルタリング機能を補ってくれる便利な拡張機能が、「Multiple Filter Masonry」。
このスクリプトを「Masonry」と一緒に組み込むことで、カンタンにフィルタリング機能が追加された「Masonry」としてタイルレイアウトを表示できます。
まずはサンプルをご覧ください(レスポンシブ表示にも対応させています)!
See the Pen Masonry with filtering function using “Multiple Filter Masonry” by digistate (@digistate) on CodePen.
INDEX
HTML構造について
フィルタリング用のコード
HTMLの構造としては、フィルタリング用にinputタグでチェックボックス(type=”checkbox”)を分けたいフィルターの数だけ設置しておきます。
<div class="button-area filters"> <label class="button"> <input type="checkbox" value="group1" />Group 1 </label> <label class="button"> <input type="checkbox" value="group2" />Group 2 </label> : </div>
inputタグには、フィルターのためのカテゴライズ用テキストをvalue値にセットしておきます。
この値は、Masonryの個々のアイテムとなる要素(※後述 : article)のclassと合うようにしておきます。
また、inputタグ(チェックボックス)は、labelタグで括っておきます。
このlabel
タグには button というclassを付け、multipleFilterMasonry.js 側でこの label
をフィルター用のボタンとしてチェック状態を検出してフィルタリングを行います。
Masonry用のコード
Masonryでグリッドレイアウト対象とするエリア全体を div
タグで id(mnsry_container) を付けて括っています(idでなくてもclassでもOK)。
<div id="mnsry_container"> <!-- 1番目のアイテム --> <article class="item group1"> <h1>メインタイトル</h1> <img src="画像URL" alt="" /> </article> <!-- 2番目のアイテム --> <article class="item group2"> <h1>メインタイトル</h1> <img src="画像URL" alt="" /> </article> <!-- 以下、必要な数だけアイテムを追加 --> : </div>
Masonryの対象となる個々のアイテムは、サンプルでは記事一覧を見立ててarticle
タグで括っています。
このarticleには、item
というclass名をつけ、さらにフィルタリング用のカテゴライズ名(group1, group2,…)となるclassも個々に付けておきます。
Javascript(jQuery)の構造
まずは大前提、jQuery、Masonry、multipleFilterMasonry.jsをロードします。
<script>http://***/js/jquery.min.js</script> <script>http://***/js/masonry.pkgd.min.js</script> <script>http://***/js/multipleFilterMasonry.js</script>
Multiple Filter Masonry経由でMasonryを実行
$("#mnsry_container").multipleFilterMasonry({ itemSelector: ".item", filtersGroupSelector:".filters" } );
Masonryでは、masonry($params)
で実行しますが、multipleFilterMasonry.js経由で実行させるため、multipleFilterMasonry($params)
に置き換えます。
たったこれだけでフィルタリング機能付きのMasonryが実行されます。とっても簡単!
引数($params)には、最低限、Masonryの要素となるセレクタ(itemSelector)とmultipleFilterMasonry.jsでフィルター用のボタン(チェックボックス)を括っているフィルターグループのセレクタ(filtersGroupSelector)を指定しておきます。
基本は、たったこれだけでOKです。
さらに、filtersGroupSelectorパラメータ以外は、Masonryでサポートしている引数をそのまま引き継げるので、他に必要なパラメータがあればMasonryの仕様に則ったフォーマットで指定できます。
フィルタリング用のボタン
サンプルでは、フィルタリングに必要なチェックボックスをlabelで括って、それをボタンに見立てています。
チェックボックス(input)自体は非表示(display:none)にしているので、labelの状態(チェック、未チェック)に合わせてCSSでスタイリングできるよう、チェック状態の場合は “active” というclassを挿入するためのスクリプトを記述しています。
$(".button").find("input").change(function(){ // labelに"active" classがなければ挿入、あれば削除 $(this).parent().toggleClass("active"); });
参考 : http://qiita.com/kazu56/items/9ebc8918fb7a75da9434
Masonryの実行タイミング
今回のサンプルでは、Masonryレイアウトは3カラムでarticleの高さは、記事のサムネイルに見立てた画像の高さを基準とし固定していないため、画像が読み込まれる前にMasonryが実行されてしまうと、タイルとなる個々の要素(article)の正確な高さがMasonry側で取得できず、レイアウトが崩れてしまうので、multipleFilterMasonry
の実行は、ページの読み込みが完了してから行うようにしています。
$(window).load(function() { $("#mnsry_container").multipleFilterMasonry({ itemSelector: ".item", filtersGroupSelector:".filters" } $(".button").find("input").change(function(){ $(this).parent().toggleClass("active"); }); });
レスポンシブ(メディアクエリ)化
今回のサンプルでは、基本は3カラムのグリッドレイアウトにしています。
Masonryの各要素はarticle(.item)なので、それに33.3%の幅を指定しておきます。
#mnsry_container article{ width:33.3%; min-height:200px; }
表示幅に合わせてフレキシブルにタイルレイアウトを並べ替えるために、ここではメディアクエリで860ピクセル幅以下で2カラム(50%)に、667ピクセル幅以下では1カラム(100%)になるようにしています。
@media (max-width: 860px) { #mnsry_container article { width: 50%; min-height: 150px; } } @media (max-width: 667px) { #mnsry_container article { width: 100%; min-height: 220px; } }
あとは、画像が表示されてMasonryが実行されるまでのローディング表示や、マウスホバー時のエフェクトなどお好みでごにょごにょしてあげれば、それっぽいグリッドレイアウトの完成です!