2011-09-14 45 views
1

我想改变一个SVG对象的属性。用JS处理对象

<?xml version="1.0" encoding="UTF-8"?> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:xlink="http://www.w3.org/1999/xlink"> 
<head> 
<title>SVG use test</title> 
<script type="text/javascript"> 
function setUsedFill(uId, fill) { 
    document.getElementById(uId).instanceRoot.correspondingElement.setAttributeNS(null, 'fill', fill); 
} 
</script> 
</head> 
<body> 
<div> 
<input type="button" value="test" onclick="setUsedFill('uc1', 'yellow');"/> 
<input type="button" value="test" onclick="setUsedFill('uc2', 'red');"/> 
</div> 
<div> 
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300"> 
    <defs> 
    <circle id="c1" cx="50" cy="50" r="30" fill="green"/> 
    </defs> 
    <use id="uc1" x="0" y="0" xlink:href="#c1"></use> 
    <use id="uc2" x="100" y="100" xlink:href="#c1"></use> 
</svg> 
</div> 
</body> 
</html> 

此代码是怎么回事在Opera,Chrome和IE 9

instanceRoot.correspondingElement - 是不是在Firefox/Mozilla的

+0

注意SVG2已删除从'SVGUseElement'了'instanceRoot'访问,看到https://svgwg.org/svg2-draft/changes。 HTML#结构。 –

回答

1

运行从我可以告诉here Mozilla不支持(或甚至提到)instanceRoot属性。

的页面是最后更新于6月27日,2011年

AS一个侧面说明,在任何情况下 - 从我可以告诉 - 你需要Firefox 4以上版本才能正常使用SVG。

编辑:

或许,如果它适合你,你可以改变你的代码位:

function setUsedFill1(uId, fill) { 
    document.getElementById(uId).setAttributeNS(null, 'fill', fill); 
} 

,并称之为:

<input type="button" value="test" onclick="setUsedFill1('c1', 'yellow');"/> 

代替。

+0

有替代吗? – user800906

+0

请参阅编辑答案。 – ZenMaster

+0

首先非常感谢您的回答。 – user800906

1

在对另一个答案的评论中,你问“有没有其他的选择?”

对于SVG工作,我使用的替代方案是Raphael JavaScript库。

这是一个优秀的库,用于在Javascript中使用SVG grpahics和动画;使事情变得更容易,并且作为额外的好处,甚至可以在一些非常旧的浏览器中使用 - 包括早期版本的IE,早在IE6之前。

它与IE一起工作的原因是它透明地检测浏览器并切换到使用VML而不是SVG绘制图形。但从你作为开发人员的角度来看,你不需要知道这一点;所有你需要知道的是它可以在所有的浏览器中使用。甜。

它也不依赖于任何其他库;你不需要使用JQuery或其他任何东西来使用它(尽管如果你愿意的话,它可以正常工作)。

我现在在纯SVG中完全没有做任何工作;一切都是通过拉斐尔完成的。

+0

对D3有什么看法? – user800906

+0

@user:我还没有使用过D3,所以我不能提供意见。但从我所了解的情况来看,D3并没有为老版本的IE提供VML后备。我需要这个功能,因为我需要支持IE7和IE8(幸好不是IE6),所以如果是这样的话,那么D3就不适合我了。 – Spudley

0

虽然在文档中不太清楚,但使用元素的设置值instanceRootcurrentInstance会将def中的实际元素设置为def。至少,这是它看起来如何在Chrome和IE11上工作。 FF29仍然没有instanceRoot。

有两个调整,以获得OP的例子来工作打算:

  1. 设置C1的填充到 inherit
  2. 单击处理程序,设置使用元素的填充属性,不 instanceRoot.correspondingElement。

这里是OP的代码,修改:

<?xml version="1.0" encoding="UTF-8"?> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:xlink="http://www.w3.org/1999/xlink"> 
    <head> 
    <title>SVG use test</title> 
     <script type="text/javascript"> 
     function setUsedFill(uId, fill) { 
      /* Set the fill attribute of the <use> element, not the inner instanceRoot.correspondingElement */ 
      document.getElementById(uId).setAttributeNS(null, 'fill', fill); 
     } 
     </script> 
    </head> 
    <body> 
     <div> 
     <input type="button" value="test" onclick="setUsedFill('uc1', 'yellow');"/> 
     <input type="button" value="test" onclick="setUsedFill('uc2', 'red');"/> 
     </div> 
     <div> 
     <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300"> 
      <defs> 
      <!-- set the fill in the def to "inherit" --> 
      <circle id="c1" cx="50" cy="50" r="30" fill="inherit"/> 
      </defs> 
      <use id="uc1" x="0" y="0" xlink:href="#c1" fill="green"></use> 
      <use id="uc2" x="100" y="100" xlink:href="#c1" fill="green"></use> 
     </svg> 
     </div> 
    </body> 
    </html> 
+0

请注意[2014/15年在Chrome和Opera中支持'instanceRoot'](https://bugs.chromium.org/p/chromium/issues/detail?id=313438&can=1&q=instanceRoot%20SVG&sort=-修饰colspec = ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified)。这个例子不再适用于这些浏览器。如果对SVG 2 shadow DOM的全面支持得以实施,则可能会返回其他形式的支持。 –