我有一些简单的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。
它会影响两个后代,而这两个后代恰好是兄弟姐妹。第一个兄弟更新,但第二个没有。第二个元素的子元素也有焦点,并包含< A >标记,该标记在onclick属性中包含上述代码。
在Chrome的“开发人员工具”窗口中,如果我轻推(例如取消勾选&勾选)任何元素的任何属性,第二个兄弟更新为正确的样式。
是否有一种解决方法可以简单地通过编程“推动”WebKit做正确的事情?
我今天偶然发现了这个:Element.redraw() for prototype.js
使用:
Element.addMethods({
redraw: function(element){
element = $(element);
var n = document.createTextNode(' ');
element.appendChild(n);
(function(){n.parentNode.removeChild(n)}).defer();
return element;
}
});
但是,我注意到有时必须直接在有问题的元素上调用redraw()。有时重绘父元素并不能解决子元素正在经历的问题。
关于浏览器渲染元素方式的好文章:渲染:重绘,回流/重布局,重样式
这对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的OUTER(MOST)容器,然后将其所有内容删除到一个变量中,然后重新添加它。
它将使所有在外部容器内所做的更改可见。
$(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);
}
我来到这里,因为我需要在修改css后重新绘制Chrome中的滚动条。
如果有人有同样的问题,我通过调用这个函数来解决它:
//Hack to force scroll redraw
function scrollReDraw() {
$('body').css('overflow', 'hidden').height();
$('body').css('overflow', 'auto');
}
这种方法不是最好的解决方案,但它可能适用于所有情况,隐藏和显示需要重绘的元素可以解决所有问题。
这是我使用它的小提琴:http://jsfiddle.net/promatik/wZwJz/18/
因为每个人似乎都有自己的问题和解决方案,我想我应该添加一些适合我的东西。在Android 4.1与当前的Chrome,试图拖动一个画布在一个div溢出:隐藏,我不能得到重画,除非我添加了一个元素的父div(在那里它不会做任何伤害)。
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);
}
没有屏幕闪烁或真正的更新,并清理自己。没有全局变量或类作用域变量,只有局部变量。在移动Safari/iPad或桌面浏览器上似乎没有任何损害。
我不敢相信在2014年这仍然是一个问题。我在滚动页面时刷新页面左下角的固定位置标题框时就遇到了这个问题,标题会在屏幕上方“鬼影”。在尝试了以上所有的事情都没有成功之后,我注意到很多事情要么很慢/导致问题,因为创建非常短的DOM转播等,导致有点不自然的感觉滚动等…
我最终制作了一个固定的位置,全尺寸的div,带有pointer-events: none,并将danorton的答案应用于该元素,这似乎强制在整个屏幕上重绘,而不干扰DOM。
HTML:
<div id="redraw-fix"></div>
CSS:
div#redraw-fix {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 25;
pointer-events: none;
display: block;
}
JS:
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';
我正在开发ionic html5应用程序,在少数屏幕上我有绝对定位元素,当在IOS设备(iPhone 4,5,6,6 +)上向上或向下滚动时,我有重绘错误。
尝试了许多解决方案,没有一个是有效的,只有这个解决了我的问题。
我使用css类。fixrepaint这些绝对位置的元素
.fixRepaint{
transform: translateZ(0);
}
这已经解决了我的问题,它可能会帮助别人
我遇到了一个SVG的问题,当方向在某些情况下发生改变时,它在Chrome for Android上消失了。下面的代码没有重现它,但是我们的设置。
body {
font-family: tahoma, sans-serif;
font-size: 12px;
margin: 10px;
}
article {
display: flex;
}
aside {
flex: 0 1 10px;
margin-right: 10px;
min-width: 10px;
position: relative;
}
svg {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.backgroundStop1 {
stop-color: #5bb79e;
}
.backgroundStop2 {
stop-color: #ddcb3f;
}
.backgroundStop3 {
stop-color: #cf6b19;
}
<article>
<aside>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="100%" width="100%">
<defs>
<linearGradient id="IndicatorColourPattern" x1="0" x2="0" y1="0" y2="1">
<stop class="backgroundStop1" offset="0%"></stop>
<stop class="backgroundStop2" offset="50%"></stop>
<stop class="backgroundStop3" offset="100%"></stop>
</linearGradient>
</defs>
<rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" fill="url(#IndicatorColourPattern)"></rect>
</svg>
</aside>
<section>
<p>Donec et eros nibh. Nullam porta, elit ut sagittis pulvinar, lacus augue lobortis mauris, sed sollicitudin elit orci non massa. Proin condimentum in nibh sed vestibulum. Donec accumsan fringilla est, porttitor vestibulum dolor ornare id. Sed elementum
urna sollicitudin commodo ultricies. Curabitur tristique orci et ligula interdum, eu condimentum metus eleifend. Nam libero augue, pharetra at maximus in, pellentesque imperdiet orci.</p>
<p>Fusce commodo ullamcorper ullamcorper. Etiam eget pellentesque quam, id sodales erat. Vestibulum risus magna, efficitur sed nisl et, rutrum consectetur odio. Sed at lorem non ligula consequat tempus vel nec risus.</p>
</section>
</article>
经过一天半的摸索,我对这里提供的俗气的解决方案并不满意,我发现这个问题是由于它在绘制新元素时似乎将元素保留在内存中引起的。解决方案是让SVG上的线性梯度的ID是唯一的,即使它在每页只使用一次。
这可以通过许多不同的方式实现,但对于我们的angular应用程序,我们使用lodash uniqueId函数向作用域添加一个变量:
Angular指令(JS):
scope.indicatorColourPatternId = _.uniqueId('IndicatorColourPattern');
HTML的更新:
第5行:<linearGradient ng- atr -id="{{indicatorColourPatternId}}" x1="0" x2="0" y1="0" y2="1">
第11行:<rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" ng- atr -fill="url(#{{indicatorColourPatternId}})" / >
我希望这个答案能让其他人省下一天砸键盘的时间。
我试着回答了更多的问题,但对我没用。
我有麻烦有相同的clientWidth与safari与其他浏览器相比,这段代码解决了这个问题:
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})
这真的很奇怪,因为如果我尝试在get_safe_value之后再次获得clientWidth,我用safari获得了一个坏值,getter必须在sty之间。transform = "translateZ(1px)";
和猪圈。Transform = "";
另一个肯定有效的解决方法是
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
问题是你失去了焦点和滚动状态。
我发现@morewry的出色回答解决了我的问题,而且will-change属性已经到达。
CSS将会改变,或者其他后续的规范将是未来的解决方案,很可能。
在我的例子中,will-change: transform的值;单独在Safari 14中有效。
.wont-update {
will-change: transform;
/* for Safari < 9.1 */
transform: translateZ(0);
}
https://developer.mozilla.org/en-US/docs/Web/CSS/will-change
https://caniuse.com/will-change