-
-
Save madrobby/1362093 to your computer and use it in GitHub Desktop.
forceRerenderOnWebkit: -> | |
@el.parentNode.style.cssText += ';-webkit-transform:rotateZ(0deg)' | |
@el.parentNode.offsetHeight | |
@el.parentNode.style.cssText += ';-webkit-transform:none' |
Why do you concat to cssText?
Using style.WebkitTransform = 'rotateZ(0deg)'; would probably do the same while being a bit faster.
And btw, why do you want to force repaint?
The concat works on any browser, not just Webkit, it just silently fails. I need to repaint because I've stumbled upon some rendering glitches with Webkit (the repaint forces the element to be correctly rendered).
isn't any 3d transform forcing a re-rendering 'cause the element is transmitted to the gpu?
@helgri yeah, but it need to be flipped on, rendered once (the offsetHeight forces a recalculation/repaint) and then switched off again so you can use it more than once on a given element. you can even use "normal" CSS properties, like "height" for example, or you could toggle "display". I choose this because I know that I won't use it for this particular element, and so I don't need to store the old value, etc.
I was wondering more if there's an approach where I don't need to mess with CSS at all.
Node.prototype.repaint = function () {
var
offsetHeight = "offsetHeight",
parentNode = this.parentNode
;
return parentNode && (offsetHeight in parentNode) ?
parentNode[offsetHeight] :
this[offsetHeight]
;
};
I see... and the rotation value works for you, because you know, that you don't use it. in other sites this may break...
you could also add/remove a .repaint class (with your rule), than it's also not necessary to store old values.
so best solution would be to avoid dom operations at all... what about adding/removing a css rule for the element to the stylesheet doc via javascript? won't touch the dom.
Have you tried modifying the class name and/or id? It worked for me on several occasions, eg. forcing iOS 5 to render position:fixed
iframes whine scrolling. Any change triggered a rerender, so appending a bogus class or assigning to the id
worked.
Should be enough to get the computed style of the element to force a repaint.
I don't have a better solution, but your suggestion just fixed a bug I had in Opera. Thanks :-)
I also found this plugin:
http://plugins.jquery.com/files/jquery.forceredraw-1.0.3.js_.txt
It confirms @KrofDrakula's suggestion for most cases but also has a "brutal" fallback where it changes CSS as you do in your suggestion, just using a 1ms timeout before it changes it back
@gr2m: It would seem the "brutal" version here changing the padding seems a bit overkill; I use the following code for a rock solid repaint:
function forceRedraw(el) {
var t = el.ownerDocument.createTextNode(' ');
el.appendChild(t);
setTimeout(function() { el.removeChild(t); }, 0);
}
@gr2m damn, i just suggested a class named "repaint", not "redraw" ;)
but i still favor a solution which doesn't need to touch the dom at all
Hi guys! Thanks to all for the suggestions... So, anyone know what is the most optimal way to force a reflow? Any jsPerf there? :)
I'll add this one to the pile https://gist.github.com/digitalicarus/c83d9b4c80ab35f7452a
Anyone know of a better way?