Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Css 如何强制WebKit重绘/重绘以传播样式更改?_Css_Google Chrome_Safari_Webkit - Fatal编程技术网

Css 如何强制WebKit重绘/重绘以传播样式更改?

Css 如何强制WebKit重绘/重绘以传播样式更改?,css,google-chrome,safari,webkit,Css,Google Chrome,Safari,Webkit,我有一些简单的JavaScript来实现样式更改: sel = document.getElementById('my_id'); sel.className = sel.className.replace(/item-[1-9]-selected/,'item-1-selected'); return false; 这适用于最新版本的FF、Opera和IE,但不适用于最新版本的Chrome和Safari 它影响到两个后代,他们碰巧是兄弟姐妹。第一个兄弟更新,但第二个兄弟不更新。第二个元素的子

我有一些简单的JavaScript来实现样式更改:

sel = document.getElementById('my_id');
sel.className = sel.className.replace(/item-[1-9]-selected/,'item-1-selected');
return false;
这适用于最新版本的FF、Opera和IE,但不适用于最新版本的Chrome和Safari

它影响到两个后代,他们碰巧是兄弟姐妹。第一个兄弟更新,但第二个兄弟不更新。第二个元素的子元素也有焦点,并包含标记,该标记在onclick属性中包含上述代码

在Chrome“Developer Tools”窗口中,如果我轻推(例如,取消选中并检查)任何元素的任何属性,则第二个同级更新为正确的样式


有没有一种解决方法可以通过编程轻松地“推动”WebKit做正确的事情?

我发现了一些复杂的建议和许多不起作用的简单建议,但对其中一个建议的评论提供了一个简单的解决方案,强制重新绘制/重新绘制效果良好:

sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='';
如果它适用于“块”以外的样式,我会让其他人评论


谢谢,瓦西里

danorton解决方案对我不起作用。我遇到了一些非常奇怪的问题,webkit根本不会画一些元素;输入中的文本直到onblur才更新;更改类名不会导致重新绘制

我无意中发现,我的解决方案是在脚本之后向主体添加一个空样式元素

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

...
doSomethingThatWebkitWillMessUp();
...

这就解决了问题。这有多奇怪?希望这对某人有所帮助。

我今天偶然发现:

使用:

Element.addMethods({
  redraw: function(element){
    element = $(element);
    var n = document.createTextNode(' ');
    element.appendChild(n);
    (function(){n.parentNode.removeChild(n)}).defer();
    return element;
  }
});
但是,我注意到有时必须直接对有问题的元素调用redraw()。有时重画父元素并不能解决子元素遇到的问题


关于浏览器呈现元素的方式的好文章:

由于display+offset触发器对我不起作用,我在这里找到了一个解决方案:

i、 e

这对JS来说很好

sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='block';
但在Jquery中,尤其是当您只能使用$(document).ready并且由于任何特定原因无法绑定到对象的.load事件时,以下操作将起作用

您需要获取对象/div的外部(大多数)容器,然后将其所有内容删除到变量中,然后重新添加它。 它将使外部容器内所做的所有更改可见

$(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);
}

我发现这种方法在处理转换时非常有用

$element[0].style.display = 'table'; 
$element[0].offsetWidth; // force reflow
$element.one($.support.transition.end, function () { 
    $element[0].style.display = 'block'; 
});

我也遇到了同样的问题。danorton的“切换显示”修复在添加到动画的步进功能时确实对我有效,但我担心性能,并寻找其他选项

在我的情况下,没有重新绘制的元素位于绝对位置元素中,而该元素当时没有z索引。向该元素添加z索引改变了Chrome的行为,并按预期重新绘制->动画变得平滑

我怀疑这是否是一种灵丹妙药,我想这取决于为什么Chrome选择不重新绘制元素,但我在这里发布了这个具体的解决方案,希望有人能帮上忙

干杯, 抢劫


tl;dr>>尝试向元素或其父元素添加z索引。

由于某些原因,我无法得到danorton的答案,我可以看到它应该做什么,因此我对其进行了一些调整:

$('#foo').css('display', 'none').height();
$('#foo').css('display', 'block');
这对我来说很有效。

在我的情况下,“display/offsetHeight”黑客不起作用,至少当它应用于正在设置动画的元素时是如此

我有一个下拉菜单,可以打开/关闭页面内容。菜单关闭后(仅在webkit浏览器中),工件会留在页面内容上。“显示/远视”黑客的唯一方法是我把它应用到身体上,这看起来很恶心

然而,我确实找到了另一个解决方案:

  • 在元素开始动画之前,在元素上添加一个定义“-webkit backface visibility:hidden;”的类(我猜您也可以使用内联样式)
  • 完成动画制作后,删除类(或样式)

  • 这仍然是一个非常粗糙的问题(它使用CSS3属性来强制硬件渲染),但至少它只会影响所讨论的元素,并且对我在PC和Mac上的safari和chrome都有效。

    我来到这里是因为我需要在更改css后在chrome中重新绘制滚动条

    如果有人有同样的问题,我通过调用以下函数来解决:

    //Hack to force scroll redraw
    function scrollReDraw() {
        $('body').css('overflow', 'hidden').height();
        $('body').css('overflow', 'auto');
    }
    
    这种方法不是最好的解决方案,但它可以处理所有问题,隐藏和显示需要重画的元素可以解决所有问题


    这是我使用的小提琴:

    这似乎与此有关:

    第一个响应中建议的解决方案在这些场景中对我很有效,即:在进行样式更改后,向主体应用并移除一个虚拟类:

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

    这将迫使safari重新绘制。

    以下操作有效。它只需要在纯CSS中设置一次。而且它比JS函数更可靠。性能似乎没有受到影响

    @-webkit-keyframes androidBugfix {from { padding: 0; } to { padding: 0; }}
    body { -webkit-animation: androidBugfix infinite 1s; }
    

    因为每个人似乎都有自己的问题和解决方案,我想我应该添加一些适合我的东西。在Android 4.1上,使用当前的Chrome浏览器,尝试在一个div中拖动画布,并使用overflow:hidden,除非我在父div中添加了一个元素,否则我无法重新绘制(这样做不会造成任何伤害)


    没有屏幕闪烁或真正的更新,并清理后,我自己。没有全局或类范围的变量,只有局部变量。在移动Safari/iPad或桌面浏览器上似乎没有任何问题。

    我们最近遇到了这个问题,并发现将受影响的元素升级到CSS中的with可以解决这个问题,而不需要额外的JavaScript

    .willnotrender { 
       transform: translateZ(0); 
    }
    
    由于这些绘制问题主要出现在Webkit/Blink中,并且此修复程序主要针对Webkit/Blink,因此在某些情况下更可取。尤其是因为被接受的答案几乎肯定会引起一场争论,而不仅仅是重新粉刷

    Webkit和Blink已经开始工作
    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);
    }
    
    .willnotrender { 
       transform: translateZ(0); 
    }
    
    Search
        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);
        }
    
    <div id="redraw-fix"></div>
    
    div#redraw-fix {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 25;
        pointer-events: none;
        display: block;
    }
    
    sel = document.getElementById('redraw-fix');
    sel.style.display='none';
    sel.offsetHeight; // no need to store this anywhere, the reference is enough
    sel.style.display='block';
    
    $el.html($el.html());
    
    element.innerHTML = element.innerHTML;
    
    document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    
    $(svgDiv).append($(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
    
    .fixRepaint{
        transform: translateZ(0);
    }
    
    //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);
    
    $('body').css('display', 'table').height();
    $('body').css('display', 'block');
    
    sel = document.getElementById('my_id');
    forceReflowJS( sel );
    return false;
    
    .selector {
        content: '1'
    }
    
    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})
    
    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
    
    @keyframes redraw{
        0% {opacity: 1;}
        100% {opacity: .99;}
    }
    
    // ios redraw fix
    animation: redraw 1s linear infinite;
    
    function forceRepaint() {
        requestAnimationFrame(()=>{
          const e=document.createElement('DIV');
          e.style='position:fixed;top:0;left:0;bottom:0;right:0;background:#80808001;\
                   pointer-events:none;z-index:9999999';
          document.body.appendChild(e);
          requestAnimationFrame(()=>e.remove());  
        });
    }
    
     document.body.style.display = 'flex';
     setTimeout(() => (document.body.style.display = ''), 0);