Search code examples
javascriptfor-loopoffsetheight

Javascript element offsetHeight returns returns 0 in for loop


I am trying to dynamically get the height of a child element inside a three column grid.

When i is equal to 2 or when i is greater than 1 (i.e. when there are at minimum 2 elements inside the loop), offsetHeight returns the rendered height correctly (I display the rendered height value in a dedicated $('#testheight') element for checking.)

However when i is equal to 1, offsetHeight returns 0, even though the rendered element has a height (there is an <img> element rendered inside the child element via PHP).

I cannot find the error! Please help!

function makeGrid(){
  var blocks = document.getElementById("grid_container").children;
  var pad = 0, cols = 3, newleft, newtop;
  var max_height = 0;
  var newoffsetheight = 0;
  for(var i = 1; i < blocks.length; i++){
    if (i % cols == 0) {
      newtop = (blocks[i-cols].offsetTop + blocks[i-cols].offsetHeight) + pad;
      max_height = Math.max(max_height, newtop + blocks[i-cols].offsetHeight);
      blocks[i].style.top = newtop+"px";
      newoffsetheight = blocks[i].offsetHeight;
    }
    else {
      if(blocks[i-cols]){
        newtop = (blocks[i-cols].offsetTop + blocks[i-cols].offsetHeight) + pad;
        blocks[i].style.top = newtop+"px";
      }
      newleft = (blocks[i-1].offsetLeft + blocks[i-1].offsetWidth) + pad;
      blocks[i].style.left = newleft+"px";
      newoffsetheight = blocks[i].offsetHeight;
    }
  }
  $('#testheight').html(newoffsetheight);
}

Solution

  • improved the code, check it out: https://jsfiddle.net/0otvhgkg/8/

    function renderGrid(){
    var blocks = document.getElementById("grid_container").children;
    var pad = 0, cols = 3, newleft
    var newtop = 0
    var max_height = blocks.length ? blocks[0].offsetHeight : 0;
    
        for(var i = 1; i < blocks.length; i++){
            if (i % cols == 0) {
                newtop = (blocks[i-cols].offsetTop + blocks[i-cols].offsetHeight) + pad;     
              blocks[i].style.top = newtop+"px";
              max_height = Math.max(max_height, newtop + blocks[i].offsetHeight);
            } else {
                if(blocks[i-cols]){
                    newtop = (blocks[i-cols].offsetTop + blocks[i-cols].offsetHeight) + pad;
                    blocks[i].style.top = newtop+"px";
                    max_height = Math.max(max_height, newtop + blocks[i-cols].offsetHeight);
                }
                newleft = (blocks[i-1].offsetLeft + blocks[i-1].offsetWidth) + pad;
                blocks[i].style.left = newleft+"px";
                max_height = Math.max(max_height, newtop + blocks[i-1].offsetHeight);
            }
      }
        $('#grid_container').css('height', max_height);
    }
    window.addEventListener("load", renderGrid, false);
    window.addEventListener("resize", renderGrid, false);
    

    Problem was we calculated max_height only when new row was created and didn't care about the first row whatsoever.