連載
» 2013年06月10日 18時00分 公開

Pinterest風グリッドレイアウトを作ってみようjQuery×HTML5×CSS3を真面目に勉強(3)(4/4 ページ)

[山田 直樹,クラスメソッド]
前のページへ 1|2|3|4       

JavaScriptの実装4 - 各グリッドの幅を個別に設定できるようにする

 ここまでは異なる高さのグリッドを並べるための実装でしたが、幅に関しては全て同じ幅に固定されていました。

 そこで各グリッドに任意の値を指定することで異なる幅のグリッドを生成して並べられるようにカスタマイズしてみたいと思います。

実装方法を定義

 幅を設定したいグリッドをどうやって指定するか、幅の基準はどうするかを決めます。なるべく手軽に指定できるようにしたいので、今回は次のようにします。

  1. 任意のグリッド要素のHTMLタグにdata属性を使って幅を設定する
  2. デフォルトのグリッド幅を基準として、基準となるグリッド1個分、2個分・・・、といったように指定する

 HTML5には、HTMLの名前空間に属さないユーザーオリジナルの属性を定義する機能が備わっています。これを独自データ属性と呼びます。よく知らない、より詳しく知りたいという方は、こちらのページをご参照ください。

 以下のように記述することで、任意のグリッド要素に幅を設定します。

<div class="grid" data-size="2">
    <div class="imgholder">
        <img src="http://media-cache-ec3.pinimg.com/192x/34/c5/e2/34c5e2172503fa9a5aa719ee4e541202.jpg">
    </div>
    <h2>3 | Photo title</h2>
    <p>For a foster child who's been passed around from home to home, a little piece of hope is lost at each transition. This week, your support will give them a duffel ...</p>
    <div class="meta">by Annie onto style.</div>
</div>
HTML

 続いてJavaScriptです。主にグリッドを配置するロジックが以下のように変わります。

//gridが配置されるx座標値、y座標値を取得
var getGridPosition = function(size) {
    if (size > 1) {
        var arrayLimit = gridArray.length - size,
            defined = false,
            tempHeight;
        for (var i=0; i<gridArray.length; i++) {
            var obj = gridArray[i],
                x = obj.x;
            if (x >= 0 && x <= arrayLimit) {
                var heightArray = getHeightArray(x, size);
                if (!defined) {
                    defined = true;
                    tempHeight = heightArray;
                    tempHeight.x = x;
                } else {
                    if (heightArray.max < tempHeight.max) {
                        tempHeight = heightArray;
                        tempHeight.x = x;
                    }
                }
            }
        }
        return tempHeight;
    } else {
        return getHeightArray(0, gridArray.length);
    }
};
//gridを配置
var setPosition = function(grid) {
    //check grid size
    var size;
    if (!grid.data('size') || grid.data('size') < 0) {
        size = 1;
    } else if (grid.data('size') > numOfCol) {	// extra
        size = numOfCol;
    } else {
        size = grid.data('size');
    }
    // gridの情報を定義
    var pos = [];
    var tempHeight = getGridPosition(size);	// extra
    pos.x = tempHeight.x;
    if (size > 1) {
        pos.y = tempHeight.max;
    } else {
        pos.y = tempHeight.min;
    }
    var gridWidth = colWidth * size - (grid.outerWidth() - grid.width());	// extra
    // gridのスタイルを更新
    grid.css({
        'width': gridWidth - opts.offsetX * 2,	// extra
        'left': pos.x * colWidth,
        'top': pos.y,
        'position': 'absolute'
    });
    // gridArrayを新しいgridで更新
    removeGridArray(pos.x, size);
    pushGridArray(pos.x, pos.y, size, grid.outerHeight());
};
JavaScript

 まず独自データ属性でサイズが指定されているかをチェックします。指定されていなければサイズ1とし、されていればその指定のサイズとします。ただし最大カラム数を超えたサイズが指定されていた場合は、最大カラム数と等しい値をサイズとして上書きします。

 次にグリッドが配置されるx座標値とy座標値を取得します。今まではグリッドをカラム順序に沿った座標位置を取得するだけでしたが、グリッドにサイズが設けられたことにより、1行当たりの残りカラム数の幅にグリッドが収まりきるかどうかを判断する処理が必要になりました。収まるようならこれまで通りの座標値を取得し、収まりきらず改行して配置する必要がある場合は、そちらの座標値を取得するようにします。

 また、指定されたグリッドのサイズに応じてwidth値も変化するため、それを算出する処理も1行加えます。

 これで改修は終わりです。こちらから実際の動きを確認できます。

おわりに

 従来とは一味違ったこのグリッドレイアウトは、Pinterestを始めファッション性の高いWebサイトでよく見かけます。以前このシリーズで紹介したパララックスエフェクト(関連記事)と並ぶトレンドだったといっても過言ではないでしょう。トレンドだっただけにこの手のレイアウトを実現するプラグインは探せばいくつか出てきますが、筆者としては自作することによってアルゴリズムを理解する良いトレーニングになったと思います。

 今回作成したのは他に出回っているプラグインに比べていくらか機能の少ないシンプルなモノとなっていますが、もしご興味ある方がおりましたら、当ソースコードをフォークして、より高機能にカスタマイズしていただければ幸いです。

著者プロフィール

山田直樹(やまだ なおき)

クラスメソッドではたらくフロントエンド・エンジニア。JavaScript・HTML・CSSによる開発を主な生業とする一方、スタイリッシュかつクールなデザインを何よりも愛していることから、UIデザインを担当することもしばしば。実はプログラムよりも洋服を自作するのが一番得意だったりする。

クラスメソッド 開発ブログ山田直樹


前のページへ 1|2|3|4       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。