2012-10-08 64 views
2

我在那里三个圆圈绘制一个SVG文件:呼叫SVG javascript函数里面的html javascript函数

<?xml version="1.0"?> 
<svg width="450" height="80" xmlns="http://www.w3.org/2000/svg"> 
    <script> 
    document.fillCircle = function(id) { 
     var circles = document.getElementsByTagName('circle'), 
      circle = document.getElementById(id); 

     [].forEach.call(circles, function(circle) { 
      circle.setAttribute('fill','#ffffff'); 
     }); 

     circle.setAttribute('fill', '#000000'); 
    } 
    </script> 
    <g> 
     <line y1="35" x1="35" y2="35" x2="375" stroke-width="3" stroke="#000000"/> 
     <circle id="state1" r="30" cy="35" cx="35" stroke-width="3" stroke="#000000" fill="#ffffff" onclick="fillCircle(this.id);"/> 
     <circle id="state2" r="30" cy="35" cx="205" stroke-width="3" stroke="#000000" fill="#ffffff" onclick="fillCircle(this.id);"/> 
     <circle id="state3" r="30" cy="35" cx="375" stroke-width="3" stroke="#000000" fill="#ffffff" onclick="fillCircle(this.id);"/> 
    </g> 
</svg> 

出于测试目的,我有onclick=""方法,但实际上这个文件是我的HTML文档中的对象:

<object id="test" data="test-vector.svg" width="100px" height="100px"></object> 

我有一个数据集,这三个点表示每个项目的“进步”。我定期通过从服务器拉出新列表来更新JSON集。对于每个项目更改,我想更新实心圆。

我想更新基于一些JavaScript的svg。但是,我无法让它进入SVG的DOM。我不在乎fillCircle()是否在svg内,如果我必须使用<embed><object>或其他东西,但是这种javascript对我不起作用。

<html> 
<body> 
    <object id="test" data="test-vector.svg"></object> 
    <script> 
     var svg = document.getElementById('test'); 
     console.log(svg); 
     svg.fillCircle('state2'); 
    </script> 
</body> 
</html> 

我试过几件事情我上找到因此,像this onethis one,但无论我考,例外总是:

Uncaught TypeError: Object #<HTMLObjectElement> has no method 'fillCircle' 

回答

5

var object = document.getElementById("test")将让你的对象元素,但你不能调用该对象直到该对象已经加载。一旦你有了,你可以使用object.contentDocument来处理嵌入式svg文档。

<html> 
<body> 
    <object id="test" data="test-vector.svg" onload="f()" ></object> 
    <script> 
     function f() { 
      var svg = document.getElementById('test'); 
      svg.contentDocument.fillCircle('state2'); 
     } 
    </script> 
</body> 
</html> 
+0

很明显我没有想到对象的负载。感谢您的信息。我不喜欢'onload ='f()'作为个人偏好的问题,但是你指出了我的正确方向!快速回答的荣誉! –

+0

@robert从一点实验看来,这似乎不起作用如果SVG的脚本被导入并且没有嵌入,也就是说fillCircle在SVG导入的外部js文件中,那么这是预期的行为还是有另外一种方法? –

+0

@DavidSmith你应该另外提一个关于它的问题 –

2

为什么不直接在您的HTML代码中嵌入SVG(使用SVG标签)? According to W3,这适用于所有现代浏览器(并且IE> = 9)。访问和更改界与JS性能,然后琐碎......

<html> 
    <body> 
     <svg>...</svg> 
    </body> 
</html> 


如果你想保持你的HTML/SVG结构虽然,你可以做到以下几点:

var svg = document.getElementById("test"); 
svg.onload = function(){ 
    svg.contentDocument.fillCircle("state2"); 
}; 

的技巧是等待SVG对象加载(onload事件);直到那时你才能安全地使用contentDocument属性。顺便说一句,这也是描述in this solution on SO(你发布了一个链接)。 ;)

+0

我不喜欢将svg嵌入到我的文档中,因为我需要把它放在那里大概30-40次,我更喜欢把它放在一个文档中,然后嵌入它,然后所有这些30-40次。关于加载,我明显错过了答案的重点,我想出了'contentDocument'使用情况,但没有负载也失败了。 @罗伯特 - 朗森对他的回答只是早一点,但是谢谢你的好解释! :) –