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

查看:27
本文介绍了访问在外部 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" 的 javascript 等价物是什么?

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 的use"元素,而不是图像.这样做的原因是SVG use元素的DOM接口指定了一个属性instanceRoot",它可以让你得到那个use元素对应的实例树"的根: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 似乎没有为 use 元素实现 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天全站免登陆