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

» 2013年06月10日 18時00分 公開
[山田 直樹,クラスメソッド]

JavaScriptの実装3 - jQueryプラグイン化する

 最後にJavaScriptコードをjQueryプラグインとして外出しします。オプションとして渡せるパラメータは以下にしました。

  • offsetX
  • offsetY
  • gridElement
  1. ;(function($) {
  2. $.fn.pinterestGrid = function(options) {
  3. elements = $(this);
  4. winObject = $(window);
  5. opts = $.extend({}, $.fn.pinterestGrid.defaults, options);
  6. setCol();
  7. applyPinterestGrid();
  8. winObject.unbind('resize').resize(function() {
  9. var containerWidth;
  10. var winWidth = winObject.width() - opts.offsetX * 2;
  11. if(winWidth < colwidth * numOfCol) {
  12. setCol();
  13. containerWidth = colwidth * (numOfCol - 1);
  14. } else if (winWidth > colwidth * (numOfCol + 1)) {
  15. setCol();
  16. containerWidth = colwidth * (numOfCol + 1);
  17. }
  18. if (containerWidth) {
  19. var current = elements.width();
  20. elements.width(colwidth * numOfCol);
  21. applyPinterestGrid();
  22. }
  23. });
  24. return this;
  25. }
  26. // デフォルトオプション
  27. $.fn.pinterestGrid.defaults = {
  28. offsetX: 5,
  29. offsetY: 5,
  30. gridElement: 'div'
  31. };
  32. var elements,
  33. winObject,
  34. numOfCol,
  35. opts = {},
  36. colwidth,
  37. gridArray = [];
  38. //IE用にArray.indexOfメソッドを追加
  39. if (!Array.prototype.indexOf) {
  40. Array.prototype.indexOf = function(elt /*, from*/) {
  41. var len = this.length >>> 0;
  42. var from = Number(arguments[1]) || 0;
  43. from = (from < 0) ? Math.ceil(from) : Math.floor(from);
  44. if (from < 0) {
  45. from += len;
  46. }
  47. for (; from < len; from++) {
  48. if (from in this && this[from] === elt) {
  49. return from;
  50. }
  51. }
  52. return -1;
  53. };
  54. }
  55. // 初期化
  56. function applyPinterestGrid() {
  57. createEmptyGridArray();
  58. elements.children(opts.gridElement).each(function(index) {
  59. setPosition($(this));
  60. });
  61. //最後にエレメントの高さを設定
  62. var heightarr = getHeightArray(0, gridArray.length);
  63. elements.height(heightarr.max + opts.offsetY);
  64. }
  65. // カラムの数とwidthを設定する
  66. function setCol() {
  67. colwidth = $(opts.gridElement).outerWidth() + opts.offsetX * 2;
  68. numOfCol = Math.floor((winObject.width() - opts.offsetX * 2) / colwidth);
  69. }
  70. //空のgridArrayを作成
  71. function createEmptyGridArray() {
  72. //最初にgridArrayを初期化
  73. gridArray = [];
  74. for(var i=0; i<numOfCol; i++) {
  75. pushGridArray(i, 0, 1, -opts.offsetY);
  76. }
  77. }
  78. //gridArrayに新しいgridを追加
  79. function pushGridArray(x, y, size, height) {
  80. //define grid object based on grid width
  81. for(var i=0; i<size; i++) {
  82. var grid = [];
  83. grid.x = x + i;
  84. grid.size = size;
  85. grid.endY = y + height + opts.offsetY*2;
  86. gridArray.push(grid);
  87. }
  88. }
  89. //gridArrayからgridを削除
  90. function removeGridArray(x, size) {
  91. for(var i=0; i<size; i++) {
  92. //remove grid beside
  93. var index = getGridIndex(x+i);
  94. gridArray.splice(index, 1);
  95. }
  96. }
  97. // gridのx値を基準にgridのインデックスを検索
  98. function getGridIndex(x) {
  99. for(var i=0; i<gridArray.length; i++) {
  100. var obj = gridArray[i];
  101. if(obj.x == x) {
  102. return i;
  103. }
  104. }
  105. }
  106. //gridのx値とサイズに基づいてgridArrayにある高さの最小値と最大値、最小値のあるx値を取得
  107. //retrun min and max height
  108. function getHeightArray(x, size) {
  109. var heightArray = [];
  110. var temps = [];
  111. for(var i=0; i<size; i++) {
  112. var idx = getGridIndex(x+i);
  113. temps.push(gridArray[idx].endY);
  114. }
  115. heightArray.min = Math.min.apply(Math, temps);
  116. heightArray.max = Math.max.apply(Math, temps);
  117. heightArray.x = temps.indexOf(heightArray.min);
  118. return heightArray;
  119. }
  120. //gridが配置されるx座標値、y座標値を取得
  121. function getGridPosition() {
  122. var pos = [];
  123. var tempHeight = getHeightArray(0, gridArray.length);
  124. pos.x = tempHeight.x;
  125. pos.y = tempHeight.min;
  126. return pos;
  127. }
  128. //gridを配置
  129. function setPosition(grid) {
  130. //check grid size
  131. if(!grid.data('size') || grid.data('size') < 0) {
  132. grid.data('size', 1);
  133. }
  134. //define grid data
  135. var pos = getGridPosition();
  136. var gridWidth = colwidth * grid.data('size') - (grid.outerWidth() - grid.width());
  137. //update style first before get grid height
  138. grid.css({
  139. 'left': pos.x * colwidth,
  140. 'top': pos.y,
  141. 'position': 'absolute'
  142. });
  143. var gridHeight = grid.outerHeight();
  144. //gridArrayを新しいgridで更新
  145. removeGridArray(pos.x, grid.data('size'));
  146. pushGridArray(pos.x, pos.y, grid.data('size'), gridHeight);
  147. }
  148. })(jQuery);
jquery.pinterestGrid.js

 これでプラグイン化できました。jQueryプラグインについては、こちらの記事(画像スライドショーでjQueryプラグインの基本を学ぶ)で詳しく解説しています。

 最後に呼び出し部分です。以下のようにオプション指定して呼び出します。

  1. $(function() {
  2. $(window).on('load', function() {
  3. $('#container').pinterestGrid({
  4. offsetX: 8,
  5. offsetY: 8,
  6. gridElement: '.grid'
  7. });
  8. });
  9. });
pinterestgrid.html(※JS部分のみ)

 これでようやく完成です。こちらから実際の動きを確認できます。

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

HTML5�偽X 險倅コ九Λ繝ウ繧ュ繝ウ繧ー

譛ャ譌・譛磯俣

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

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

メールマガジン登録

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