2

This is not a question regarding column layouts before someone links to one of those.

I have two boxes of text in different areas of a page that I want to be the same height. They are rendered asynchronously with jQuery. I load the data with something like this:

$.ajax({
  url: someUrl,
  dataType: 'html',
  type: 'GET',
  success: function(data) {
    $(mySelector).html(data)
  },
  complete: function() {
    adjustHeights()
  }
})

adjustHeights is getting called (the reference is valid even though I clipped stuff out). The selector returns the appropriate elements too. I get the heights of all the things that match the selector and then apply the maximum height of the current ones (say one is 38px tall and one is 50px tall it returns 50px) to all of them.

The problem is that while adjustHeights works perfectly fine if I call it some time after the content is loaded (say on a button click or via debugger) when it runs here it's getting the height before everything is rendered. I suspect custom font-faces may be playing a part but I'm not sure.

Is there a good way to tell jQuery "No seriously, don't run this until everything is rendered for real.". My understanding is that this should already be happening but is not.

Edit Just verified that this problem goes away if I get rid of the font-face or the line-height that's in the CSS.

Jared
  • 1,450
  • 1
  • 13
  • 25
  • ``You could use a small timeout `` – Andrew Whitaker Jan 04 '12 at 01:06
  • Seeing some live code would be helpful if possible. Make sure you're using [`HTMLElement.offsetHeight`](https://developer.mozilla.org/en/DOM/element.offsetHeight) to get the heights, `.height()` gets the content height excluding borders and padding. If that doesn't work then @AndrewWhitaker might have the best solution. I don't believe there are any events fired when fonts are rendered. – Ansel Santosa Jan 04 '12 at 01:11
  • 1
    [http://jsfiddle.net/](http://jsfiddle.net/) – Tomas Reimers Jan 04 '12 at 02:08
  • Andrew, add your hack as an answer and (as much as it pains me to because it is totally a hack) I'll accept it. I tried using various heights as well as trying to calculate the number of lines that are there and multiplying by what the line-height should be, but it seems like the combination of a custom font face and a changed line height causes late rendering in at least Chrome :P – Jared Jan 04 '12 at 14:24

2 Answers2

1

You might find that you can use a timeout of zero. Often when inserting content into the DOM successive js is run before the DOM has completely updated. This is most obvious when doing animation straight after replacing content in the DOM, it can be jerky and even jump straight to the final state. In your case it seems dimensions haven't quite updated before you need them. A (hacky - Andrew is right) way around this is:

setTimeout(adjustHeights, 0);
baseten
  • 1,362
  • 1
  • 13
  • 34
  • This is also discussed in [this thread](http://stackoverflow.com/questions/779379/why-does-settimeoutfn-0-sometimes-help) and at greater detail by John Resig [here](http://ejohn.org/blog/how-javascript-timers-work/) – baseten Jan 04 '12 at 22:04
  • I'm actually seeing the best results with setTimeout(adjustHeights, 50) or something along those lines. You're links are super handy though and should point people in the right direction in the future so thanks! – Jared Jan 06 '12 at 02:35
0

I don't suppose you've tried the following?

complete: function() {
    $(document).ready(function () {
        adjustHeights();
    });
}

Also, you have an extraneous comma after the 'complete' definition.

Hope this helps.

pete
  • 24,141
  • 4
  • 37
  • 51
  • Good point about the comma, will change. The real code was in coffeescript and did some other things so this was a quick (and apparently sloppy) change to plain JS. I did try that and it didn't work :( – Jared Jan 06 '12 at 02:33