2012-10-08 61 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'使用情況,但沒有負載也失敗了。 @羅伯特 - 朗森對他的回答只是早一點,但是謝謝你的好解釋! :) –