Beating the IE Resize Bug

So it turns out that there are actually a number of problems with the solution I've proposed in this blog entry. It seems to work for my sample page, but when put to the test in a real world scenerio, it failed miserably.

An updated solution has been posted: Beating the IE Resize Bug (revisited).

And you can see this updated solution in action here.

There is a bug (at least I consider it a bug) in IE (versions 6 and 7) in which the clarity between window.onresize and body.onresize is muddied. This can cause quite a problem for developers and even render the client's browser unresponsive (throttling the CPU to near 100%) if you're not very careful.

I've discussed this with numerous members of the IE development team, and I was able to gain some valuable insight. The general feeling was that this behavior is by design. It may be (and I can understand the motivation to do this), but I'm still not so sure I agree with it (it just doesn't feel logical to me).

After quite a bit of back-and-forth, I finally got in touch with one developer who seemed to think that this is the wrong behavior (in strict mode). Personally, I feel that this behavior is undesirable in either strict mode or transitional, but I guess just having the issue acknowledged is a good start.

The problem remains though, because this bug affects developers today, and it won't be addressed for quite some time (if I'm not mistaken, the official IE7 release is not going to address it).

So in this blog entry, my goal is to introduce a work-around that I've come up with for dealing with this issue.

Read on to learn more.

First, let me demonstrate the bug:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>IE Resize Bug</title>

    <script type = "text/javascript">
      function init()
      {
        window.onresize = function()
        {
          alert('The browser window was resized… or was it?');
        };
      }

      function grow()
      {
        var p = document.createElement('p');
        p.appendChild(document.createTextNode('I am a paragraph!'));
        document.body.appendChild(p);
      }
    </script>

    <style type = "text/css">
      body
      {
        margin: 0;
        padding: 0;
        width: auto;
        height: auto;
        border: 3px solid red;
      }
    </style>
  </head>

  <body onload = "init();">
    <button id = "btnGrow" onclick = "grow();">Grow</button>
  </body>
</html>

If you save the above code sample and run it in IE, you'll see that IE thinks it's logical to fire the window's resize event every time the grow() function execute. Why? Because the <body> element was resized to accomodate the newly added <p> tag, and IE fails to make any distinction between the window (or viewport) and the <body> element.

Contrast this with Firefox, which correctly understands that the window size has not changed, and therefore, the resize event should not fire. Seems like a no-brainer if you ask me.

So how do you make IE fire the resize event only when it should fire the resize event? Unfortunately, you can't.

The only solution I've been able to come up with is to forget the built-in resize event completely and write some custom code to manage it instead.

One of the IE developers suggested a work-around which involved monitoring the placement of a fixed-positioned <div> element. I like this approach (a lot actually), but it's usefulness is limited since IE6 doesn't support CSS fixed positioning.

To see the solution I've developed, goto part 2.

Pages: 1 2

5 Responses

  1. Kai Says:

    Works great horizontally, but if I want to fit a div vertically in the browser window with no scrolling, this doesn't quite work. I resorted to adding another condition in the doResize function, comparing the document clientHeight to scrollHeight and resize my div if the absolute > 20. 20 because apparently there is some natural difference between the two even if there is no scrolling. It makes it jumpy (not great), but it works.

  2. Stephen Stchur Says:

    Kai:

    Double check to be sure you're using the updated technique, which can be found here: The IE Resize Bug (Revisited). That blog post utilizes a better technique which I discovered after I posted this blog entry.

    To the best of my knowledge, the newer technique works in all cases.

  3. Wilfried Nauta Says:

    Dear Sir,

    Thanks to your efforts I finally understand the cause of this problem.

    However, this piece of Javascript will work fine too in most cases:

    var wheight = 0;
    var temp_height = 0;
    var delay = 100;

    function init(){
    if(self.innerHeight)temp_height = self.innerHeight; //all except Explorer
    else if(document.documentElement && document.documentElement.clientHeight)temp_height = document.documentElement.clientHeight; // Explorer 6 Strict Mode
    else if(document.body)temp_height = document.body.clientHeight;// other Explorers
    else temp_height = 430;
    if(temp_height!=height)dosomething();
    wheight = temp_height;
    setTimeout('init()',delay);
    }

    window.onload = init;

    Best regards, WN

  4. Pedro Says:

    Simple but effective solution:

    function countViewport(){
    winHeight = $(window).height();
    winWidth = $(window).width();
    }

    $(window).bind('resize', function(){
    if ($(window).height() != winHeight
    || $(window).width() != winWidth) {
    countViewport();
    // TODO here
    }
    });

  5. Wal Says:

    I do not recommend the use of Internet Explorer because it is very stupid

    I would recommend the use of the browser is always the best FireFox

Got something to say?

Please note: Constructive criticism is welcome. Rude or vulgar comments however, are not and will be removed during moderation.