elastic-columns.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. (function($)
  2. {
  3. $.elasticColumns = function(element, options)
  4. {
  5. this.defaults =
  6. {
  7. columns: 3,
  8. innerMargin: 10,
  9. outerMargin: 10
  10. };
  11. this.settings = {};
  12. this.$element = $(element);
  13. this.columns = [];
  14. /**
  15. * Inits
  16. */
  17. this.init = function()
  18. {
  19. this.settings = $.extend({}, this.defaults, options);
  20. this.buildLayout();
  21. };
  22. /**
  23. * Builds the layout using the given settings
  24. */
  25. this.buildLayout = function()
  26. {
  27. var $items = this.$element.children(':not(.elastic-columns-ignore)');
  28. var container_width = this.$element.width();
  29. var column_width = (container_width - (this.settings.innerMargin * (this.settings.columns - 1)) - (this.settings.outerMargin * 2)) / this.settings.columns;
  30. for(var index = 0; index < this.settings.columns; index += 1)
  31. {
  32. this.columns[index] = this.settings.outerMargin;
  33. }
  34. // Iterates into elements
  35. for(var item_id = 0; item_id < $items.length; item_id += 1)
  36. {
  37. var $item = $($items.get(item_id));
  38. // Looks for the smallest column
  39. var smallest_column = 0;
  40. for(var column_id = 0; column_id < this.settings.columns; column_id += 1)
  41. {
  42. if (this.columns[column_id] < this.columns[smallest_column])
  43. {
  44. smallest_column = column_id;
  45. }
  46. }
  47. // Gets the item padding
  48. var horizontal_padding = parseInt($item.css('padding-left') )+ parseInt($item.css('padding-right'));
  49. var vertical_padding = parseInt($item.css('padding-top') )+ parseInt($item.css('padding-bottom'));
  50. // Sets the item CSS properties
  51. $item.css('position', 'absolute');
  52. $item.css('width', (column_width - horizontal_padding) + 'px');
  53. $item.css('left', (this.settings.outerMargin + (this.settings.innerMargin * smallest_column) + (smallest_column * column_width)) + 'px');
  54. $item.css('top', this.columns[smallest_column] + 'px');
  55. // Updates columns height
  56. this.columns[smallest_column] += $item.outerHeight() + this.settings.innerMargin + vertical_padding;
  57. }
  58. // Looks for the highest column and sets the container height
  59. var highest_column = 0;
  60. for(var column_id = 0; column_id < this.settings.columns; column_id += 1)
  61. {
  62. if (this.columns[column_id] > this.columns[highest_column])
  63. {
  64. highest_column = column_id;
  65. }
  66. }
  67. this.$element.outerHeight(this.columns[highest_column] + 'px');
  68. };
  69. /**
  70. * Destroys the layout restoring its initial appearance
  71. */
  72. this.destroyLayout = function()
  73. {
  74. // Iterates into elements and clear the styles set by the plugin
  75. var $items = this.$element.children(':not(.elastic-columns-ignore)');
  76. for(var item_id = 0; item_id < $items.length; item_id += 1)
  77. {
  78. var $item = $($items.get(item_id));
  79. $item.css({'position':'','width':'','left':'','top':''});
  80. }
  81. // Restores the container's height
  82. this.$element.css({'height':''});
  83. };
  84. };
  85. $.fn.elasticColumns = function(options, option, value)
  86. {
  87. return this.each(function()
  88. {
  89. // Plugin instanciation
  90. var plugin = $(this).data('elasticColumns');
  91. if (typeof plugin == 'undefined')
  92. {
  93. plugin = new $.elasticColumns(this, options);
  94. $(this).data('elasticColumns', plugin);
  95. plugin.init();
  96. }
  97. // API calls
  98. else
  99. {
  100. if (options == 'refresh')
  101. {
  102. plugin.buildLayout();
  103. }
  104. if (options == 'set')
  105. {
  106. plugin.settings[option] = value;
  107. }
  108. if (options == 'destroy')
  109. {
  110. plugin.destroyLayout();
  111. }
  112. }
  113. });
  114. }
  115. })(jQuery);