連載
Pinterest風グリッドレイアウトを作ってみよう:jQuery×HTML5×CSS3を真面目に勉強(3)(3/4 ページ)
jQueryを使って、女性に人気の写真共有SNS、Pinterestのグリッドレイアウトを再現してみよう。
JavaScriptの実装3 - jQueryプラグイン化する
最後にJavaScriptコードをjQueryプラグインとして外出しします。オプションとして渡せるパラメータは以下にしました。
- offsetX
- offsetY
- gridElement
;(function($) { $.fn.pinterestGrid = function(options) { elements = $(this); winObject = $(window); opts = $.extend({}, $.fn.pinterestGrid.defaults, options); setCol(); applyPinterestGrid(); winObject.unbind('resize').resize(function() { var containerWidth; var winWidth = winObject.width() - opts.offsetX * 2; if(winWidth < colwidth * numOfCol) { setCol(); containerWidth = colwidth * (numOfCol - 1); } else if (winWidth > colwidth * (numOfCol + 1)) { setCol(); containerWidth = colwidth * (numOfCol + 1); } if (containerWidth) { var current = elements.width(); elements.width(colwidth * numOfCol); applyPinterestGrid(); } }); return this; } // デフォルトオプション $.fn.pinterestGrid.defaults = { offsetX: 5, offsetY: 5, gridElement: 'div' }; var elements, winObject, numOfCol, opts = {}, colwidth, gridArray = []; //IE用にArray.indexOfメソッドを追加 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) { from += len; } for (; from < len; from++) { if (from in this && this[from] === elt) { return from; } } return -1; }; } // 初期化 function applyPinterestGrid() { createEmptyGridArray(); elements.children(opts.gridElement).each(function(index) { setPosition($(this)); }); //最後にエレメントの高さを設定 var heightarr = getHeightArray(0, gridArray.length); elements.height(heightarr.max + opts.offsetY); } // カラムの数とwidthを設定する function setCol() { colwidth = $(opts.gridElement).outerWidth() + opts.offsetX * 2; numOfCol = Math.floor((winObject.width() - opts.offsetX * 2) / colwidth); } //空のgridArrayを作成 function createEmptyGridArray() { //最初にgridArrayを初期化 gridArray = []; for(var i=0; i<numOfCol; i++) { pushGridArray(i, 0, 1, -opts.offsetY); } } //gridArrayに新しいgridを追加 function pushGridArray(x, y, size, height) { //define grid object based on grid width for(var i=0; i<size; i++) { var grid = []; grid.x = x + i; grid.size = size; grid.endY = y + height + opts.offsetY*2; gridArray.push(grid); } } //gridArrayからgridを削除 function removeGridArray(x, size) { for(var i=0; i<size; i++) { //remove grid beside var index = getGridIndex(x+i); gridArray.splice(index, 1); } } // gridのx値を基準にgridのインデックスを検索 function getGridIndex(x) { for(var i=0; i<gridArray.length; i++) { var obj = gridArray[i]; if(obj.x == x) { return i; } } } //gridのx値とサイズに基づいてgridArrayにある高さの最小値と最大値、最小値のあるx値を取得 //retrun min and max height function getHeightArray(x, size) { var heightArray = []; var temps = []; for(var i=0; i<size; i++) { var idx = getGridIndex(x+i); temps.push(gridArray[idx].endY); } heightArray.min = Math.min.apply(Math, temps); heightArray.max = Math.max.apply(Math, temps); heightArray.x = temps.indexOf(heightArray.min); return heightArray; } //gridが配置されるx座標値、y座標値を取得 function getGridPosition() { var pos = []; var tempHeight = getHeightArray(0, gridArray.length); pos.x = tempHeight.x; pos.y = tempHeight.min; return pos; } //gridを配置 function setPosition(grid) { //check grid size if(!grid.data('size') || grid.data('size') < 0) { grid.data('size', 1); } //define grid data var pos = getGridPosition(); var gridWidth = colwidth * grid.data('size') - (grid.outerWidth() - grid.width()); //update style first before get grid height grid.css({ 'left': pos.x * colwidth, 'top': pos.y, 'position': 'absolute' }); var gridHeight = grid.outerHeight(); //gridArrayを新しいgridで更新 removeGridArray(pos.x, grid.data('size')); pushGridArray(pos.x, pos.y, grid.data('size'), gridHeight); } })(jQuery);
jquery.pinterestGrid.js
これでプラグイン化できました。jQueryプラグインについては、こちらの記事(画像スライドショーでjQueryプラグインの基本を学ぶ)で詳しく解説しています。
最後に呼び出し部分です。以下のようにオプション指定して呼び出します。
$(function() { $(window).on('load', function() { $('#container').pinterestGrid({ offsetX: 8, offsetY: 8, gridElement: '.grid' }); }); });
pinterestgrid.html(※JS部分のみ)
これでようやく完成です。こちらから実際の動きを確認できます。
Copyright © ITmedia, Inc. All Rights Reserved.