[英]Internet Explorer draws SVG incorrectly when updating xlink:href for a <use> element
https://jsfiddle.net/swoq9g3f/1/
我在用JavaScript更改xlink:href
后,在Internet Explorer(v11.0.9600.17728)中错误地绘制了一个简单的SVG时遇到问题。
如果仅在IE中渲染SVG,则会得到两个同心圆。 javascript将<use>
元素的xlink:href
值设置为#def1
,这是之前的值。 此后,IE仅渲染较大的圆圈,而较小的圆圈隐藏在其后面。 较小的圆圈位于svg文档的后面,这意味着它应始终显示在较大圆圈的顶部。 我还包括对forceRedraw()
一些调用,但是它们forceRedraw()
问题。
在Chrome或Firefox中不会发生此问题。 是什么原因造成的? 有办法解决该问题吗?
SVG:
<svg id="svg_element" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400">
<defs>
<svg id="def1" width="300" height="300">
<g>
<circle cx="150" cy="150" r="100" />
<circle cx="150" cy="150" r="50" />
</g>
</svg>
<svg id="def2">
<use id="use_element" xlink:href="#def1" />
</svg>
</defs>
<g fill="white" stroke="black" >
<use xlink:href="#def2" />
</g>
</svg>
使用Javascript:
document.getElementById("use_element").setAttributeNS('http://www.w3.org/1999/xlink','href','#def1')
document.getElementById("def1").forceRedraw()
document.getElementById("def2").forceRedraw()
document.getElementById("svg_element").forceRedraw()
我找到了解决该问题的方法。
https://jsfiddle.net/swoq9g3f/9/
似乎更改<defs>
中的内容并不总是会触发完整的重新绘制,因此我必须诱使它随后进行重新绘制。 在此示例中,我发现更改SVG顶层<g>
中的<use>
正确触发了重新绘制。
SVG:
<svg id="svg_element" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400">
<defs>
<svg id="def1" width="300" height="300">
<g>
<circle cx="150" cy="150" r="100" />
<circle cx="150" cy="150" r="50"/>
</g>
</svg>
<svg id="def2">
<use id="use_element" xlink:href="#def1" />
</svg>
</defs>
<g fill="white" stroke="black">
<use id="use_element_2" xlink:href="#def2" />
</g>
</svg>
使用Javascript:
document.getElementById("use_element").setAttributeNS('http://www.w3.org/1999/xlink','href','#def1')
document.getElementById("use_element_2").setAttributeNS('http://www.w3.org/1999/xlink','href','#def2')
在更新xlink:href="..."
,在IE中会发生这种情况,但在更新clip-path=url(...)
时,也会发生这种情况。 问题在于DOM不是最新的,需要刷新,可以手动强制进行。
要强制进行更新(立即,同步重排或重排),可以读取诸如offsetTop
类的元素属性。 这将迫使浏览器重新绘制元素,然后才能为您提供offsetTop
值。
在本次演讲中提到了这一点: 更快的HTML和CSS:Web开发人员的布局引擎内部 (在37:10)
我使用此功能,每当更改svg时,我都将其称为。
function repaintThisElement(element){
var tmp = 0;
if (navigator.appName == 'Microsoft Internet Explorer'){
tmp = elementOnShow.parentNode.offsetTop + 'px';
}else{
tmp = elementOnShow.offsetTop;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.