-
Notifications
You must be signed in to change notification settings - Fork 78
/
Copy pathjquery.row-grid.js
114 lines (106 loc) · 4.14 KB
/
jquery.row-grid.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
(function($){
$.fn.rowGrid = function( options ) {
return this.each(function() {
if(options === 'appended') {
options = $(this).data('grid-options');
var $lastRow = this.children('.' + options.lastRowClass);
var items = $lastRow.nextAll().add($lastRow);
layout(this, options, items);
} else {
options = $.extend( {}, $.fn.rowGrid.defaults, options );
$(this).data('grid-options', options);
layout(this, options);
if(options.resize) {
$(window).on('resize.rowGrid', {container: this}, function(event) {
layout(event.data.container, options);
});
}
}
});
};
$.fn.rowGrid.defaults = {
minMargin: null,
maxMargin: null,
resize: true,
lastRowClass: 'last-row',
firstItemClass: null
};
function layout(container, options, items) {
var rowWidth = 0,
rowElems = [],
items = items || container.querySelectorAll(options.itemSelector),
itemsSize = items.length;
for(var index = 0; index < itemsSize; ++index) {
items[index].removeAttribute('style');
if (items[index].classList) {
items[index].classList.remove(options.firstItemClass, options.lastRowClass);
}
else {
// IE <10
items[index].className = items[index].className.replace(new RegExp('(^|\\b)' + options.firstItemClass + '|' + options.lastRowClass + '(\\b|$)', 'gi'), ' ');
}
}
// read
var containerWidth = container.clientWidth-parseFloat($(container).css('padding-left'))-parseFloat($(container).css('padding-right'));
var itemAttrs = [];
for(var i = 0; i < itemsSize; ++i) {
itemAttrs[i] = {
outerWidth: items[i].offsetWidth,
height: items[i].offsetHeight
};
}
// write
for(var index = 0; index < itemsSize; ++index) {
rowWidth += itemAttrs[index].outerWidth;
rowElems.push(items[index]);
// check if it is the last element
if(index === itemsSize - 1) {
for(var rowElemIndex = 0; rowElemIndex<rowElems.length; rowElemIndex++) {
// if first element in row
if(rowElemIndex === 0) {
rowElems[rowElemIndex].className += ' ' + options.lastRowClass;
}
rowElems[rowElemIndex].style.marginRight = (rowElemIndex < rowElems.length - 1)?options.minMargin+'px' : 0;
}
}
// check whether width of row is too high
if(rowWidth + options.maxMargin * (rowElems.length - 1) > containerWidth) {
var diff = rowWidth + options.maxMargin * (rowElems.length - 1) - containerWidth;
var nrOfElems = rowElems.length;
// change margin
var maxSave = (options.maxMargin - options.minMargin) * (nrOfElems - 1);
if(maxSave < diff) {
var rowMargin = options.minMargin;
diff -= (options.maxMargin - options.minMargin) * (nrOfElems - 1);
} else {
var rowMargin = options.maxMargin - diff / (nrOfElems - 1);
diff = 0;
}
var rowElem,
widthDiff = 0;
for(var rowElemIndex = 0; rowElemIndex<rowElems.length; rowElemIndex++) {
rowElem = rowElems[rowElemIndex];
var rowElemWidth = itemAttrs[index+parseInt(rowElemIndex)-rowElems.length+1].outerWidth;
var newWidth = rowElemWidth - (rowElemWidth / rowWidth) * diff;
var newHeight = Math.round(itemAttrs[index+parseInt(rowElemIndex)-rowElems.length+1].height * (newWidth / rowElemWidth));
if (widthDiff + 1 - newWidth % 1 >= 0.5 ) {
widthDiff -= newWidth % 1;
newWidth = Math.floor(newWidth);
} else {
widthDiff += 1 - newWidth % 1;
newWidth = Math.ceil(newWidth);
}
rowElem.style.cssText =
'width: ' + newWidth + 'px;' +
'height: ' + newHeight + 'px;' +
'margin-right: ' + ((rowElemIndex < rowElems.length - 1)?rowMargin : 0) + 'px';
if(rowElemIndex === 0) {
rowElem.className += ' ' + options.firstItemClass;
}
}
rowElems = [],
rowWidth = 0;
}
}
}
})(jQuery);