2010-07-27 74 views
10

SVG標準允許使用和引用外部SVG文件。訪問外部SVG文件中定義的DOM對象

我有一個文件circle.svg,它定義了一個ID爲「the_circle」的圓形對象。 從主要的SVG文件中,我可以包含這個圓圈並使用SVG linking對它進行動畫處理。

我也想通過javascript訪問同一個圓對象,我該怎麼做? 什麼是相當於xlink:href="url(#the_image)#the_circle"的JavaScript?

使用document.getElementById('the_image')我只能訪問SVGImageElement,但不能訪問SVG中定義的對象。

<?xml version="1.0" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg width="100%" height="100%" version="1.1" 
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" > 

    <image 
    id="the_image" 
    x="0" y="0" width="100%" height="100%" 
    xlink:href="circle.svg" /> 

    <animateTransform  
    xlink:href="url(#the_image)#the_circle" 

    attributeName="transform" attributeType="XML" 
    type="translate" 
    from="0" to="25" 
    dur="1s" repeatCount="indefinite" 
    additive="replace" fill="freeze" /> 
</svg> 
+0

發佈在SVG-開發商http://tech.groups.yahoo.com/group/svg-developers/message/63940 – rodrigob 2010-07-29 14:50:18

回答

13

看起來這樣做的「正確」方法實際上是使用SVG「use」元素,而不是圖像。原因是SVG use元素的DOM接口指定了一個屬性「instanceRoot」,它允許您獲取與該使用元素對應的「實例樹」的根:http://www.w3.org/TR/SVG/struct.html#InterfaceSVGUseElement

因此,您將結束了,看起來像下面這樣的解決方案: circle.svg:

<?xml version="1.0" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg width="4in" height="4in" id="the_svg" 
    viewBox="0 0 4 4" version="1.1" 
    xmlns="http://www.w3.org/2000/svg"> 
    <circle r="1" fill="blue" stroke="none" id="the_circle"/> 
</svg> 

文件,它使用circle.svg的SVG根節點:

<?xml version="1.0" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg width="100%" height="100%" id="foo" 
    version="1.1" 
    xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"> 

    <use xlink:href="circle.svg#the_svg"/> 
</svg> 

但不幸的是,儘管Firefox支持ü se的使用元素與外部文件,目前Webkit中有一個不允許這樣的錯誤:https://bugs.webkit.org/show_bug.cgi?id=12499

此外,Firefox似乎沒有實現使用元素的instanceRoot屬性。

因此,看起來您可能需要解決當前SVG實施的限制。我建議這樣做的方式是使用XMLHttpRequest下載您想要鏈接的文檔,並將下載的文檔的DOM導入到主機文檔的DOM中。下面的代碼實現這一點,在Firefox,Opera和鉻工作:

<?xml version="1.0" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg width="100%" height="100%" id="foo" 
    version="1.1" 
    xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"> 

    <script> 
    function fetchXML (url, callback) { 
     var xhr = new XMLHttpRequest(); 
     xhr.open('GET', url, true); 
     xhr.onreadystatechange = function (evt) { 
     //Do not explicitly handle errors, those should be 
     //visible via console output in the browser. 
     if (xhr.readyState === 4) { 
      callback(xhr.responseXML); 
     } 
     }; 
     xhr.send(null); 
    }; 

    //fetch the document 
    fetchXML("http://localhost:8082/tmp/circle.svg",function(newSVGDoc){ 
     //import it into the current DOM 
     var n = document.importNode(newSVGDoc.documentElement,true); 
     document.documentElement.appendChild(n); 

     var circle = document.getElementById("the_circle"); //now you have the circle 
    }) 
    </script> 
</svg> 
+0

感謝您的回答同樣的問題! – rodrigob 2010-07-31 20:48:52

+0

XHR ...輝煌。 – Duke 2011-08-19 08:46:53

+0

這正是我正在尋找的!其他嘗試通過XHR獲取SVG並將其附加到DOM沒有成功。謝謝! – 2013-12-31 09:28:06

1

爲了補充@回聲流與jQuery中/ CoffeeScript的代碼出色的解決方案:

$.get '/assets/hexagon.svg', (svgFileData)-> 
    svgTag = svgFileData.documentElement 
    $('body').append(svgTag) 
    circle = $('#the_circle') 
+0

不要忘記使用document.importNode導入節點。它可能會抱怨,如果你不這樣做。 – jbeard4 2011-08-19 19:15:24

11

您可以訪問必要的元件容易一點:

document.getElementById('the_image').contentDocument.getElementById('the_circle') 

參見this image參考(採取dev.opera.comenter image description here

+0

不錯,但有什麼收穫?我認爲這隻適用於包含在同一個域中的SVG? – joeytwiddle 2013-07-09 15:57:33

+0

又等什麼?一般來說,你想操縱你的文件,而不是來自其他網站的文件。 – 2013-07-10 09:02:02

+0

我會把它當作是的;很好清楚。我同意同域通常是這種情況,除非真正需要一個通用的解決方案,否則其他答案會過於複雜。 – joeytwiddle 2013-07-11 09:45:44

相關問題