Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
354 views
in Technique[技术] by (71.8m points)

javascript - 在Chrome / Mac上强制DOM重绘/刷新(Force DOM redraw/refresh on Chrome/Mac)

Every once in a while, Chrome will render perfectly valid HTML/CSS incorrectly or not at all.(Chrome有时会不正确地显示或完全不显示完全有效的HTML / CSS。)

Digging in through the DOM inspector is often enough to get it to realize the error of its ways and redraw correctly, so it's provably the case that the markup is good.(通过DOM检查器进行挖掘通常足以使它意识到其方式的错误并正确地重绘,因此,可以证明标记是好的。) This happens frequently (and predictably) enough in a project I'm working on that I've put code in place to force a redraw in certain circumstances.(在我正在研究的项目中,这种情况经常发生(并且可以预测)到足以在某些情况下强制执行重绘的代码位置。)

This works in most browser/os combinations:(这适用于大多数浏览器/操作系统组合:)

    el.style.cssText += ';-webkit-transform:rotateZ(0deg)'
    el.offsetHeight
    el.style.cssText += ';-webkit-transform:none'

As in, tweak some unused CSS property, then ask for some information that forces a redraw, then untweak the property.(如前所述,调整一些未使用的CSS属性,然后要求提供一些信息以强制重绘,然后取消调整该属性。)

Unfortunately, the bright team behind Chrome for the Mac seem to have found a way to get that offsetHeight without redrawing.(不幸的是,Mac版Chrome背后的聪明团队似乎找到了一种无需重新绘制即可获取offsetHeight的方法。) Thus killing an otherwise useful hack.(从而杀死本来有用的黑客。)

Thus far, the best I've come up with to get the same effect on Chrome/Mac is this piece of ugliness:(到目前为止,我想出的在Chrome / Mac上获得相同效果的最好方法是:)

    $(el).css("border", "solid 1px transparent");
    setTimeout(function()
    {
        $(el).css("border", "solid 0px transparent");
    }, 1000);

As in, actually force the element to jump a bit, then chill a second and jump it back.(在这种情况下,实际上是迫使元素跳一点,然后冷静一秒钟再跳回去。)

Making it worse, if you drop that timeout below 500ms (to where it would be less noticeable), it often won't have the desired effect, since the browser won't get around to redrawing before it goes back to its original state.(更糟糕的是,如果将超时时间降低到500ms以下(不太明显),由于浏览器在返回原始状态之前无法进行重绘,因此通常无法达到预期的效果。)

Anybody care to offer a better version of this redraw/refresh hack (preferably based on the first example above) that works on Chrome/Mac?(有人愿意提供适用于Chrome / Mac的此重绘/刷新hack(最好基于上述第一个示例)的更好版本吗?)

  ask by Jason Kester translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Not sure exactly what you're trying to achieve but this is a method I have used in the past with success to force the browser to redraw, maybe it will work for you.(不确定您要实现的目标是什么,但这是我过去成功使用的一种方法,它可以迫使浏览器重新绘制,也许对您有用。)

// in jquery
$('#parentOfElementToBeRedrawn').hide().show(0);

// in plain js
document.getElementById('parentOfElementToBeRedrawn').style.display = 'none';
document.getElementById('parentOfElementToBeRedrawn').style.display = 'block';

If this simple redraw doesn't work you can try this one.(如果这种简单的重绘不起作用,则可以尝试这种方法。)

It inserts an empty text node into the element which guarantees a redraw.(它在元素中插入一个空的文本节点,以确保重绘。)
var forceRedraw = function(element){

    if (!element) { return; }

    var n = document.createTextNode(' ');
    var disp = element.style.display;  // don't worry about previous display style

    element.appendChild(n);
    element.style.display = 'none';

    setTimeout(function(){
        element.style.display = disp;
        n.parentNode.removeChild(n);
    },20); // you can play with this timeout to make it as short as possible
}

EDIT: In response to ?ime Vidas what we are achieving here would be a forced reflow.(编辑:作为对?imeVidas的回应,我们在这里实现的结果是强制性回流。)

You can find out more from the master himself http://paulirish.com/2011/dom-html5-css3-performance/(您可以从大师本人身上找到更多信息http://paulirish.com/2011/dom-html5-css3-performance/)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...