April 24, 2012

JavaScript not resizing height of UL element sometimes when inserting LI elements using Jquery

Question by Fire Emblem

I have an Html/JavaScript application that contains N columns that need to be large enough contain all of the possible LI elements from all of the columns.

The simple solution seems to count the heights of all of the items in each column, compensate for padding, and then set the height to that total for each of the columns.

This works great when the LI elements contain plain text. Unfortunately, when the LI elements contain images instead, various browsers have problems. For example, when I first load the page in FireFox, it looks like the screenshot below, but upon another refresh, it works fine. It doesn’t work as expected in Chrome either.

Screenshot Showing the height of the UL element is not in sync with the LI elements

My application does not pre-populate the LI elements when the page loads – it uses JavaScript, as follows:

function populateUnsetAnswers(unsetCategoryAnswers) {
    for (i in unsetCategoryAnswers) {
        if (unsetCategoryAnswers.hasOwnProperty(i.toString())) {
            $('#categoryQuestionArea #possibleAnswers').append(
                categoryAnswerLiTag(unsetCategoryAnswers[i])
            );
        }
    }
}

function categoryAnswerLiTag(unsetCategoryAnswer) {
    var html = '<li id="' + unsetCategoryAnswer.id + '">';

    if (unsetCategoryAnswer.image) {
        html += '<img class="categoryAnswerImage" title="';
        html += unsetCategoryAnswer.text;
        html += '" src="/trainingdividend/rest/streaming/';
        html += unsetCategoryAnswer.image.fileName;
        html += '" style="height: ';
        html += unsetCategoryAnswer.image.height;
        html += ';';
        html += '" />';
    } else {
        html += unsetCategoryAnswer.text
    }

    html += '</li>';

    return html;
}

When the page is done loading, an ajax request fetches all of the objects to be put into LI elements, and then calls the first function above.

After all of the LI elements are created, I call this function right after it:

function resize() {
    var currentHeight, totalHeight;
    totalHeight = 0;

    $("#categoryQuestionArea ul").children().each(function() {
        currentHeight = $(this).height();

        totalHeight += currentHeight + 13;
    });

    $("#categoryQuestionArea ul").height(totalHeight);
    $("#categoryQuestionArea div#separator").css("padding-top", (totalHeight / 2) + "px");
}

Is there any way to tell jQuery, “Don’t call resize() until all of the LI’s are fully loaded and the images have rendered” ?

I think what’s happening is that on the initial page load, the height of these LI elements is 0 or a small value because it doesn’t contain the image, so my resize function is calculating the wrong result (I tested this with some alert statements). As long as the LIs are populated and the images have loaded, the total height is calculated just fine.

Any help? Thanks

Answer by Starx

This is rather a CSS problem, most probably due a fixed height, with items either floated or absolutely positioned.

There are number of ways to fix this.

  1. Give a min-height instead of fixing a height.

    #container { min-height: 100px; }
    
  2. Clear the float and do not set any heights

    #container { overflow: hidden; }
    
  3. Use Scripts to add up to the height, once every element is added. Like the jQuery snippet below

    $("#container").append($("#theimg"));
    $("#container").height($("#container").height()+$("#theimg").height());
    

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!