How can I force reflow after DHTML change in IE7?

2019-03-11 01:38发布

问题:

I have a page where the user can dynamically add file upload boxes. Adding the boxes changes the height of the div they are in, but certain elements of the div below it stay in the same place, so they start to overlap with the new DOM elements.

This works correctly in IE8, Firefox, Chrome. How can I force IE7 to reflow the page with the new DHTML?

The best solution I worked out was this:

window.resizeBy(1, 0); 
setTimeout(UndoResize, 0);

But it doesn't work with a maximized window (it restores the window).

回答1:

Try:

element.className = element.className;

on the modified div (or possibly its parent, or even a more remote ancestor, depending on various factors such as relatively-positioned containment).

As the className has been assigned a value IE will reflow and repaint that portion of the page in case the CSS affecting that element has changed. Luckily, it isn't optimised to check if the className value actually changed from its previous value, so the above will trigger the reflow without breaking anything else.

I did find one occasion when this fixed IE6 but broke IE7, but try it and see if it works for you.



回答2:

I've just wasted incredible amounts of time on this absolutely ridiculous bug (manifesting in IE7 only), in the webpage way too complex to put the code here, where element.className = element.className wasn't working.

The ultimate solution for IE7 (well, tested at least in the place I've encountered the bug) seems to be executing ALL of the lines below as a hook to any DOM changes:

try{
    element.parentNode.style.cssText += "";
    element.parentNode.style.zoom = 1;
    element.style.cssText += "";
    element.style.zoom = 1;
}catch(ex){}

We've already had the first two lines (surrounded with try-catch) in our framework for a long time, but it turned out insufficient in some particular scenario, but adding the next two fixed this.

Tested both in maximized and non-maximized window.

try/catch is in place because in some certain circumstances (e.g. inside an iframe) it may generate a JS error that will break the app (this is info from my team fellow, I haven't encountered it myself).

On the contrary, for IE8, element.className = element.className seems to be doing its job (yeah, we all love conditional code for each version...)

I love Win XP as an OS, but until IE-bound people use it, we have to find dirty fixes to such crazy problems... Damn sad.


Edit 2013.03.05

The snippet above seemed to be working in most of the scenarios, but also was not enough in one place. Now we have stuff like this in our code:

try {
    var s1 = domElt.parentNode.style, s2 = domElt.style;
    var dummyCss = "foo:foo;"; // do not add leading ';' here!
    s1.cssText += "";
    s1.zoom = 1;
    s2.cssText += dummyCss;
    s2.cssText = s2.cssText.replace(dummyCss, "");
} catch (ex) {}