How can I force WebKit to redraw/repaint to propag

2018-12-31 05:01发布

I have some trivial JavaScript to effect a style change:

sel = document.getElementById('my_id');
sel.className = sel.className.replace(/item-[1-9]-selected/,'item-1-selected');
return false;

This works fine with the latest versions of FF, Opera and IE, but fails on the latest versions of Chrome and Safari.

It affects two descendants, which happen to be siblings. The first sibling updates, but the second doesn’t. A child of the second element also has focus and contains the <a> tag that contains the above code in an onclick attribute.

In the Chrome “Developer Tools” window if I nudge (e.g. uncheck & check) any attribute of any element, the second sibling updates to the correct style.

Is there a workaround to easily and programmatically “nudge” WebKit into doing the right thing?

25条回答
余生请多指教
2楼-- · 2018-12-31 05:25

above suggestions didnt work for me. but the below one does.

Want to change the text inside the anchor dynamically. The word "Search". Created an inner tag "font" with an id attribute. Managed the contents using javascript (below)

Search

script contents:

    var searchText = "Search";
    var editSearchText = "Edit Search";
    var currentSearchText = searchText;

    function doSearch() {
        if (currentSearchText == searchText) {
            $('#pSearch').panel('close');
            currentSearchText = editSearchText;
        } else if (currentSearchText == editSearchText) {
            $('#pSearch').panel('open');
            currentSearchText = searchText;
        }
        $('#searchtxt').text(currentSearchText);
    }
查看更多
弹指情弦暗扣
3楼-- · 2018-12-31 05:27

Not that this question needs another answer, but I found simply changing the color by a single bit forced a repaint in my particular situation.

//Assuming black is the starting color, we tweak it by a single bit
elem.style.color = '#000001';

//Change back to black
setTimeout(function() {
    elem.style.color = '#000000';
}, 0);

The setTimeout proved critical to move the second style change outside the current event loop.

查看更多
浮光初槿花落
4楼-- · 2018-12-31 05:27

I would recommend a less hackish and more formal way to force a reflow: use forceDOMReflowJS. In your case, your code would look as follows.

sel = document.getElementById('my_id');
forceReflowJS( sel );
return false;
查看更多
孤独总比滥情好
5楼-- · 2018-12-31 05:31

I came up here because I needed to redraw scrollbars in Chrome after changing its css.

If someone's having the same problem, I solved it by calling this function:

//Hack to force scroll redraw
function scrollReDraw() {
    $('body').css('overflow', 'hidden').height();
    $('body').css('overflow', 'auto');
}

This method is not the best solution, but it may work with everything, hiding and showing the element that needs to be redraw may solve every problem.

Here is the fiddle where I used it: http://jsfiddle.net/promatik/wZwJz/18/

查看更多
呛了眼睛熬了心
6楼-- · 2018-12-31 05:32

The only solution works for me is similar to sowasred2012's answer:

$('body').css('display', 'table').height();
$('body').css('display', 'block');

I have a lot of problem blocks on page, so I change display property of root element. And I use display: table; instead of display: none;, because none will reset scrolling offset.

查看更多
何处买醉
7楼-- · 2018-12-31 05:36

I tried morewry answer but it does not work for me. I had trouble to have the same clientWidth with safari comparing to others browsers and this code solved the problem:

var get_safe_value = function(elm,callback){
    var sty = elm.style
    sty.transform = "translateZ(1px)";
    var ret = callback(elm)//you can get here the value you want
    sty.transform = "";
    return ret
}
// for safari to have the good clientWidth
var $fBody = document.body //the element you need to fix
var clientW = get_safe_value($fBody,function(elm){return $fBody.clientWidth})

It is really strange because if I try again to get the clientWidth after get_safe_value, I obtain a bad value with safari, the getter has to be between sty.transform = "translateZ(1px)"; and sty.transform = "";

The other solution that works definitively is

var $fBody = document.body //the element you need to fix
$fBody.style.display = 'none';
var temp = $.body.offsetHeight;
$fBody.style.display = ""
temp = $.body.offsetHeight;

var clientW = $fBody.clientWidth

The problem is that you lose focus and scroll states.

查看更多
登录 后发表回答