0

I created an image grid to arrange different sizes (both width and height) images in 4 columns. The logic is, if there are 20 images, each image should be uploaded to the lowest height column. So, in the jQuery loop, I'm getting heights of all columns, then sort them and take the lowest. Then insert the image to the lowest height column. To do this, in every loop, it need to be taken the correct height of each column, but when I put an alert() and print heights in each loop, it is getting wrong heights. How can I solve this?

HTML:

<div class="row"> 
  <div class="column col1">
  </div>
  <div class="column col2">
  </div>  
  <div class="column col3">
  </div>
  <div class="column col4">
  </div>
</div>

CSS:

.row {
    display: -ms-flexbox; /* IE10 */
    display: flex;
    -ms-flex-wrap: wrap; /* IE10 */
    flex-wrap: wrap;
    padding: 0 4px;
}

/* Create four equal columns that sits next to each other */
.column {
    -ms-flex: 25%; /* IE10 */
    flex: 25%;
    max-width: 25%;
    padding: 4px;
    height: max-content;
}

jQuery:

$(document).ready(function() {

    var filesCount = 5;

    for( i = 1; i <= filesCount; i++ ) {

        var col1 = $(".col1").outerHeight();
        var col2 = $(".col2").outerHeight();
        var col3 = $(".col3").outerHeight();
        var col4 = $(".col4").outerHeight();
        var sizes = [[col1, "col1"], [col2, "col2"], [col3, "col3"], [col4, "col4"]];
        alert(sizes);

        var min = 1000000;
        var mincol;
        for ( k = 0; k < 4; k++ ) {
            if ( sizes[k][0] < min ) {
                min = sizes[k][0];
                mincol = sizes[k][1];
            }
        }
        $("." + mincol ).append("<img alt='Image" + i + "Title' src='images/image" + i + ".jpg' style='width:100%'>");
    }
});
David Johns
  • 1,254
  • 3
  • 19
  • 48
  • Maybe give this a read: https://stackoverflow.com/questions/51285308/how-do-min-content-and-max-content-work – markmoxx Dec 07 '18 at 12:26
  • What heights are you getting? They should start off as 8, due to the padding you've set on the flex items. – markmoxx Dec 07 '18 at 12:37
  • Why is there an outer loop when you are looping over same elements each time? Any images inside the columns that have to be loaded first to account for heights? Please provide a runnable [mcve] that reproduces problem – charlietfl Dec 07 '18 at 12:45

2 Answers2

1

function getMinColumnByHeight () {
  var columns = [{
    class: '.col1',
    height: $('.col1').outerHeight()
  },{
    class: '.col2',
    height: $('.col2').outerHeight()
  },{
    class: '.col3',
    height: $('.col3').outerHeight()
  },{
    class: '.col4',
    height: $('.col4').outerHeight()
  }];
   
  var min = Infinity;
  var col = undefined;
  columns.forEach( (column) => {
    if (column.height < min) {
      min = column.height;
      col = column.class;
    }
  });
  
  return col;
}

function randomHeight (min,max) {
    return Math.floor(Math.random()*( max - min + 1) + min);
}

$(document).ready(function() {
  var images = 20;
  for (var i = 0; i < images; ++i) {
    var height = randomHeight(100, 300);
    var image = 'https://picsum.photos/500/' + height + '/?random';
    var column = getMinColumnByHeight();
    $(column).append("<img alt='' src='" + image + "' style='width:100%'>");
  }
});
.row {
    display: -ms-flexbox; /* IE10 */
    display: flex;
    -ms-flex-wrap: wrap; /* IE10 */
    flex-wrap: wrap;
}

.column {
    -ms-flex: 25%; /* IE10 */
    flex: 25%;
    max-width: 25%;
    height: max-content;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row"> 
  <div class="column col1">
  </div>
  <div class="column col2">
  </div>  
  <div class="column col3">
  </div>
  <div class="column col4">
  </div>
</div>
Parn
  • 878
  • 7
  • 19
0

Try this

$(window).ready(function() {
    setTimeout(function() {
        //your code
    }, 1);
});