访问外部SVG文件中定义的DOM对象 [英] Accessing a DOM object defined in an external SVG file

查看:140
本文介绍了访问外部SVG文件中定义的DOM对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SVG标准允许使用和引用外部SVG文件。

SVG standard allows to use and refer external SVG files.

我有一个文件 circle.svg 定义一个id为the_circle的圆形对象。
从主SVG文件我可以包含这个圈子并使用动画,使用 SVG链接

I have a file circle.svg that defines a circle object with id "the_circle". From the main SVG file I am able to include this circle and animate it, using SVG linking.

我也想通过javascript访问同一个圈子对象,我该怎么做?
什么是相当于的相对应的xlink:href =url(#the_image)#the_circle

I would also like to access the same circle object via javascript, how can I do this ? What is the javascript equivalent of xlink:href="url(#the_image)#the_circle" ?

使用 document.getElementById('the_image')我只能访问SVGImageElement,但不能访问SVG内定义的对象。

Using document.getElementById('the_image') I can only access the SVGImageElement but not the objects defined inside the included 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使用元素的DOM接口指定了一个属性instanceRoot,它允许您获取与该使用元素相对应的实例树的根: http://www.w3.org/TR/SVG/struct.html#InterfaceSVGUseElement

It seems like the "right" way to do this would actually be to use an SVG "use" element, rather than an image. The reason for this is that the DOM interface of the SVG use element specifies a property "instanceRoot", which allows you to get the root of the "instance tree" corresponding to that use element: http://www.w3.org/TR/SVG/struct.html#InterfaceSVGUseElement

所以,你最终会得到一个如下所示的解决方案:
circle.svg:

So, you would end up with a solution that looks something like the following: 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根节点的文档:

Document which uses the svg root node of 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="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

Unfortunately, though, while Firefox supports use of the use element with external documents, there's currently a bug in Webkit which does not allow this: https://bugs.webkit.org/show_bug.cgi?id=12499

此外,Firefox似乎没有实现使用元素的instanceRoot属性。

Also, Firefox does not seem to implement the instanceRoot property for use elements.

所以,看来你可能需要解决当前SVG实现的局限性。我建议这样做的方法是使用XMLHttpRequest下载要链接到的文档,并将下载的文档的DOM导入到主机文档的DOM中。以下代码实现了这一点,可以在Firefox,Opera和Chromium中使用:

So, it seems you may need to work around the limitations of current SVG implementations. The way I would recommend doing this is to use XMLHttpRequest to download the document to which you would like to link, and import the DOM of the downloaded document into your host document's DOM. The following code implements this, and works in Firefox, Opera and 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>

这篇关于访问外部SVG文件中定义的DOM对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆