Monday, January 12th, 2009

Forcing a UI redraw from JavaScript

Category: JavaScript, Tip

<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:

javascript
< view plain text >
  1. Element.addMethods({
  2.   redraw: function(element){
  3.     element = $(element);
  4.     var n = document.createTextNode(' ');
  5.     element.appendChild(n);
  6.     (function(){n.parentNode.removeChild(n)}).defer();
  7.     return element;
  8.   }
  9. });

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?

Posted by Dion Almaer at 1:45 pm
12 Comments

+++--
3.8 rating from 17 votes

12 Comments »

Comments feed TrackBack URI

Even plain:

element.className = element.className

works fine for me.

Comment by oswald — January 13, 2009

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.

Comment by dbloom — January 13, 2009

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.

Comment by tomh — January 13, 2009

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.

Comment by leonyu — January 13, 2009

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.

Comment by jonathansnook — January 13, 2009

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!

Comment by Lon42 — January 13, 2009

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.

Comment by kim3er — January 14, 2009

@kim3er:

it’s especially visible when you use timeouts that change an element’s style.top property

Comment by alshur — January 28, 2009

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..

Comment by vasko — February 11, 2009

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).

Comment by bankshot — September 1, 2009

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.

Comment by martyspain — September 14, 2009

Brilliant. You just saved me from a late late night!

Comment by risingfish — December 12, 2011

Leave a comment

You must be logged in to post a comment.