2

https://jsfiddle.net/swoq9g3f/1/

xlink:href在我用 javascript更改 a 后,我遇到了一个问题,即在 Internet Explorer (v11.0.9600.17728) 中错误地绘制了一个简单的 SVG 。

如果你在 IE 中只渲染 SVG,你会得到两个同心圆。javascript 将元素的xlink:href值设置为,这是它之前的值。之后,IE 只渲染较大的圆圈,较小的圆圈隐藏在其后面。较小的圆圈在 svg 文档的后面,这意味着它应该始终呈现在较大的圆圈之上。我还包括了一些对 的调用,但它们未能纠正问题。<use>#def1forceRedraw()

在 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()
4

2 回答 2

2

我找到了解决该问题的方法。

https://jsfiddle.net/swoq9g3f/9/

似乎更改中的内容<defs>并不总是会触发完整的重绘,所以我不得不欺骗它在之后进行重绘。在此示例中,我发现更改SVG 顶层中的 正确触发了重绘<use><g>

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')
于 2015-05-11T14:29:28.410 回答
2

这发生在 IE 更新时xlink:href="...",但也更新时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;
   }
}
于 2015-10-28T12:13:14.670 回答