How can I force WebKit to redraw/repaint to propagate style changes?

后端 未结 27 2297
我寻月下人不归
我寻月下人不归 2020-11-22 02:04

I have some trivial JavaScript to effect a style change:

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


        
相关标签:
27条回答
  • 2020-11-22 02:21

    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/

    0 讨论(0)
  • 2020-11-22 02:24

    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.

    0 讨论(0)
  • 2020-11-22 02:26

    This seems related to this: jQuery style not being applied in Safari

    The solution suggested in the first response has worked well for me in these scenarios, namely: apply and remove a dummy class to the body after making the styling changes:

    $('body').addClass('dummyclass').removeClass('dummyclass');
    

    This forces safari to redraw.

    0 讨论(0)
  • 2020-11-22 02:27

    danorton solution didn't work for me. I had some really weird problems where webkit wouldn't draw some elements at all; where text in inputs wasn't updated until onblur; and changing className would not result in a redraw.

    My solution, I accidentally discovered, was to add a empty style element to the body, after the script.

    <body>
    ...
    <script>doSomethingThatWebkitWillMessUp();</script>
    <style></style>
    ...
    

    That fixed it. How weird is that? Hope this is helpful for someone.

    0 讨论(0)
  • 2020-11-22 02:27

    Since everyone seems to have their own problems and solutions, I figured I'd add something that works for me. On Android 4.1 with current Chrome, trying to drag a canvas around inside a div with overflow:hidden, I couldn't get a redraw unless I added an element to the parent div (where it wouldn't do any harm).

    var parelt = document.getElementById("parentid");
    var remElt = document.getElementById("removeMe");
    var addElt = document.createElement("div");
    addElt.innerHTML = " "; // Won't work if empty
    addElt.id="removeMe";
    if (remElt) {
        parelt.replaceChild(addElt, remElt);
    } else {
        parelt.appendChild(addElt);
    }
    

    No screen flicker or real update, and cleaning up after myself. No global or class scoped variables, just locals. Doesn't seem to hurt anything on Mobile Safari/iPad or desktop browsers.

    0 讨论(0)
  • 2020-11-22 02:27

    This is fine for JS

    sel.style.display='none';
    sel.offsetHeight; // no need to store this anywhere, the reference is enough
    sel.style.display='block';
    

    But in Jquery, and particularly when you can only use $(document).ready and cannot bind to a the .load event of an object for any particular reason, the following will work.

    You need to get the OUTER(MOST) container of the objects/divs and then remove all its contents into a variable, then re-add it. It will make ALL changes done within the outer container visible.

    $(document).ready(function(){
        applyStyling(object);
        var node = $("div#body div.centerContainer form div.centerHorizontal").parent().parent();
        var content = node.html();
        node.html("");
        node.html(content);
    }
    
    0 讨论(0)
提交回复
热议问题