Monday, January 12th, 2009
Forcing a UI redraw from JavaScript
<p>Thomas Fuchs has run into those annoying times when a redraw is required to irk the browser into a correct layout, and his weapon of choice is:-
-
Element.addMethods({
-
redraw: function(element){
-
element = $(element);
-
var n = document.createTextNode(' ');
-
element.appendChild(n);
-
(function(){n.parentNode.removeChild(n)}).defer();
-
return element;
-
}
-
});
-
This is an update to the Script.aculo.us forceRerendering so it will probably be in Scripty 2? :)
Sebastian of Qooxdoo had a similar technique:
You may also use some kind of addClass/removeClass combo. That would result into the same effect but without creating unused DOM elements. We use this method in qooxdoo and it works well.
Do you run into these issues?
Related Content:











Even plain:
element.className = element.className
works fine for me.
Changing className will cause the page’s CSS selectors to be recomputed for that element, which can be expensive on large complex pages with large stylesheets.
On some browsers, you can add then remove “outline: 0px solid black” to the inline style of the element to force a repaint.
Heh, yeah, I’ve had a function similar to this (remove/add className) in my toolkit for a while. Especially useful for when you have absolutely positioned rounded corners inside a box w/ changing content, so IE6 behaves.
Doesn’t always work. Here is a case where it does not work:
Absolute positioned DIV on IE7. Text inside the DIV. IE7 zoom is set at something other than 100%, the DIV is moved horizontally, the text does not get redrawn with the DIV.
The presented redraw function does not redraw the text. Changing className and other styles does not lead to redraw either.
I use a slight variation on Thomas Fuchs’s when I noticed some artifacting in Adobe AIR 1.5. Create an element and then pull it out. Although the class name seems like an elegant solution.
in IE: have something scroll
it will force a redraw at that very moment! and by that i mean right in the middle of your running script!
Is there anyway to prevent a redraw? I’m thinking specifically about FF redraw during JS/HTML animation. Animation that flies in most other browsers (inc. IE6) is really choppy in FF2&3, in my experience.
@kim3er:
it’s especially visible when you use timeouts that change an element’s style.top property
I use the following:
elm.style.display=”none”;
var redrawFix = elm.offsetHeight;
elm.style.display=”block”; // or other value if required
This works in all browsers I have needed it for – Opera, Konqueror, Safari and IE (including IE8 RC1 for which I just needed a redraw fix too). I haven’t ever needed it for Firefox though..
Many thanks vasko! I had a nasty Opera canvas-not-redrawing problem, yours was the only fix that worked (although I hadn’t the original one yet, I was saving the long-winded one till last).
Top stuff, I’m making a note of that one – was tearing my hair out over an inline-block repaint issue in IE7 until I tried vasco’s fix.
Brilliant. You just saved me from a late late night!