Wednesday, April 17, 2013

Really, Really, Really Resize an Iframe Window

‹prev | My Chain | next›

So it turns out that I did not, in fact, solve my problem last night.

I ran into one of those weird browser timing issues that only shows up if you reload the page a dozen times and do a little dance. The problem is with the iframe that holds the animation in my live code ICE Editor. What should look like this:



Ends up looking like:



The problem is that the window inside the iframe somehow ends up with the wrong dimensions. Instead of the smaller 600x300 size that it ought to have, it thinks that is the size of the entire browser's viewport (around 1200x800).

Yesterday I was able to reproduce the problem fairly reliably until I explicitly set the width and height of the iframe that is created to hold the preview:
// Getter for the current preview iframe element. If no preview iframe
// exists, a new one will be created.
Editor.prototype.createPreviewIframe = function() {
  var iframe = document.createElement( 'iframe' );
  iframe.width = this.preview_el.clientWidth;
  iframe.height = this.preview_el.clientHeight;
  iframe.style.border = '0';
  this.preview_el.appendChild( iframe );

  return iframe;
};
After doing this, I boldly claimed that the problem was solved and went to bed. When I woke, saw the problem again. It is harder to reproduce with this code, but I can eventually reload the page enough and do my dance just right. I do see the same behavior.

This is one of those weird cases that do not show up in StackOverflow searches. How many people are dynamically creating iframes so that they can dynamically create the web page inside that iframe? But I need to be able to do this for educational material in support of 3D Game Programming for Kids.

So I fiddle around in the JavaScript console. One of things that I love about the Chrome developer tools is that it autocompletes for all matching properties and methods—even without any letters entered:



Eventually I stumble across the resizeTo() method of a window. It turns out that calling this method on the iframe's window after the iframe has been added to the document clears up the problem:
Editor.prototype.createPreviewIframe = function() {
  var iframe = document.createElement( 'iframe' );
  iframe.width = this.preview_el.clientWidth;
  iframe.height = this.preview_el.clientHeight;
  iframe.style.border = '0';

  this.preview_el.appendChild( iframe );

  iframe.contentWindow.resizeTo(
    this.preview_el.clientWidth,
    this.preview_el.clientHeight
  );

  return iframe;
};
I am almost positive that this resolves the problem. I have reloaded the page many times and done my dance quite nicely. And it always displays correctly. Now all that remains is the sleep test. As long as it works tomorrow, I will consider this good to go.

Update: a sample page with the embedded editor.


Day #725

No comments:

Post a Comment