I prepare code like masonry.
Rules are simple: - 4 columns always - each element has the same width
My script for positioning elements looks like below (onload):
var line = 0;
var row = 0;
var heights = [];
// Count elements on one line
$('img').each(function() {
if ($(this).prev().length > 0) {
if ($(this).position().top != $(this).prev().position().top) {
return false;
}
line++;
} else {
line++;
}
});
for (i = 0; i < $('img').length; i++) {
if (i % line == 0 && i > 0) {
row++;
}
// Set position in first row
$('img:eq(' + i + ')').css({
'position': 'absolute',
'top': '0px',
'left': $('img:first').outerWidth(true) * i
});
// Set position for next rows
if (row > 0) {
$('img:eq(' + i + ')').css({
'top': parseFloat($('img:eq(' + (i - line) + ')').offset().top + $('img:eq(' + (i - line) + ')').outerHeight(true) - $('img:first').offset().top),
'left': parseFloat($('img:eq(' + (i - line) + ')').css('left'))
});
}
}
And function to remove element on click
$('img').on('click', function() {
$('img').css({
'transition': 'all 3s'
});
$(this).remove();
$(window).trigger('load');
});
I would like to ask two questions:
All code on jsfiddle: http://jsfiddle.net/n8v3X/3/
(1) div wont get height, because its children are position absolute elements, height can be set via javascript.
>> Calculate total img height in each column
>> Find which column of images have greater height and set to wrap div
/* Logic to Calculate Height */
var wrap_height = 0;
var column_array = [0, 0, 0, 0];
for (i = 0; i <= row; i++) {
var temp_height = 0;
for (j = 0; j < line; j++) {
//curr element in a row : j+ ( i * line );
var curr_height = $('img:eq(' + (j + (i * line)) + ')').outerHeight(true);
column_array[j % line] += curr_height;
}
}
for (i = 0; i < column_array.length; i++) {
if (column_array[i] > wrap_height) {
wrap_height = column_array[i];
}
}
$('#wrap').css({
height: wrap_height + 'px'
});
(b) Not properly positioned because,
the new position of prev element cant be calculated properly in loop.
$('img:eq(' + (i - line) + ')') >> top & left value get from below code, was before it get set to new position.
if (row > 0) {
$('img:eq(' + i + ')').css({
'top': parseFloat($('img:eq(' + (i - line) + ')').offset().top + $('img:eq(' + (i - line) + ')').outerHeight(true) - $('img:first').offset().top),
'left': parseFloat($('img:eq(' + (i - line) + ')').css('left'))
});
}
}
i used data attribute of html5 to fix this issue.