簡體   English   中英

訪問在外部SVG文件中定義的DOM對象

[英]Accessing a DOM object defined in an external SVG file

SVG標准允許使用和引用外部SVG文件。

我有一個文件circle.svg ,它定義了一個ID為“ the_circle”的圓對象。 在SVG主文件中,我可以使用SVG鏈接添加此圈子並為其設置動畫。

我也想通過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>

看來,“正確”的方法實際上是使用SVG“使用”元素,而不是圖像。 這樣做的原因是SVG use元素的DOM接口指定了屬性“ instanceRoot”,該屬性允許您獲取與該use元素相對應的“實例樹”的根: 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支持在外部文檔中使用use元素,但Webkit中當前存在一個錯誤,該錯誤不允許這樣做: https ://bugs.webkit.org/show_bug.cgi?id =12499

另外,Firefox似乎並未實現use元素的instanceRoot屬性。

因此,似乎您可能需要解決當前SVG實現的局限性。 我建議這樣做的方法是使用XMLHttpRequest下載要鏈接到的文檔,然后將下載的文檔的DOM導入到宿主文檔的DOM中。 以下代碼實現了此功能,並且可以在Firefox,Opera和Chromium中使用:

<?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>

您可以輕松訪問必要的元素:

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

請參閱此圖像以供參考(在dev.opera.com上拍攝) 在此處輸入圖片說明

這是使用React和ES6時解決此問題的方法。 用法:

<SvgImage url='pathToImage.svg'></SvgImage>

https://gist.github.com/mikkel/8b79a713ff06bbec379d

用jQuery / Coffeescript中的代碼補充@ echo-flow的出色解決方案:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM