Css 如何强制WebKit重绘/重绘以传播样式更改?
我有一些简单的JavaScript来实现样式更改: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 它影响到两个后代,他们碰巧是兄弟姐妹。第一个兄弟更新,但第二个兄弟不更新。第二个元素的子
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浏览器中),工件会留在页面内容上。“显示/远视”黑客的唯一方法是我把它应用到身体上,这看起来很恶心
然而,我确实找到了另一个解决方案:
这仍然是一个非常粗糙的问题(它使用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);