简体   繁体   中英

Why is the resize event constantly firing when I assign it a handler with a timeout?

I assigned a timeout to my window.resize handler so that I wouldn't call my sizable amount resize code every time the resize event fires. My code looks like this:

<script>
function init() {
  var hasTimedOut = false;
  var resizeHandler = function() {
    // do stuff
    return false;
  };

  window.onresize = function() {
    if (hasTimedOut !== false) {
      clearTimeout(hasTimedOut);
    }
    hasTimedOut = setTimeout(resizeHandler, 100); // 100 milliseconds
  };
}
</script>
<body onload="init();">
...
etc...

In IE7 (and possibly other versions) it appears that when you do this the resize event will constantly fire. More accurately, it will fire after every timeout duration -- 100 milliseconds in this case.

Any ideas why or how to stop this behavior? I'd really rather not call my resize code for every resize event that fires in a single resizing, but this is worse.

In your //do stuff code, do you manipulate any of the top,left,width,height,border,margin or padding properties?

You may unintentionally be triggering recursion which unintentionally triggers recursion which unintentionally triggers recursion...

How to fix the resize event in IE

also, see the answer for "scunliffe" "In your ... properties?

IE does indeed constantly fire its resize event while resizing is taking place (which you must know, as you are already implementing a timeout for a fix).

I am able to replicate the results you are seeing, using your code, on my test page.

However, the problem goes away if I increase the timeout to 1000 instead of 100. You may want to try with different wait values to see what works for you.

Here is the test page I used : it has a nicely dynamic wait period already set up for you to play with.

I stumbled on the same problem, but solved it differenly, and I think it's more elegant than making a timeout....

The context: I have an iframed page, loaded inside the parent page, and the iframe must notify the parent when its size changes, so the parent can resize the iframe accordingly - achieving dynamic resizing of an iframe.

So, in the iframed HTML document, I tried to register a callback on the body tag. First, on the onchange - it didn't work. Then on resize - it did work, but kept firing constantly. (Later on I found the cause - it was apparently a bug in Firefox, which tried to widen my page to infinity). I tried the ResizeObserver - for no avail, the same thing happened.

The solution I implemented was this:

<body onload="docResizePipe()">
<script>
var v = 0;
const docResizeObserver = new ResizeObserver(() => {
    docResizePipe();
});
docResizeObserver.observe(document.querySelector("body"));
function docResizePipe() {
    v += 1;
    if (v > 5) {
        return;
    }
    var w = document.body.scrollWidth;
    var h = document.body.scrollHeight;
    window.parent.postMessage([w,h], "*");
}
setInterval(function() {
    v -= 1;
    if (v < 0) {
        v = 0;
    }
}, 300);
</script>

So how it works: each time the callback fires, we increment a variable v; once in every 300 ms, we decrement it; if it's too big, the the firing is blocked.

The big advantage of this over the timeout-based solution, is that it introduces to lag for a user experience, and also clear in how exactly it does block the recursion. (Well, actually not )))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM