如何访问<img>元素中SVG文件的内容?

43

假设你的HTML中有以下代码:

<img src='example.svg' />

你如何通过JavaScript获取example.svg文件中的内容(即<rect>, <circle>, <ellipse>等)?

5个回答

42

无法从img元素获取引用的SVG的DOM。

如果您使用<object><embed><iframe>,则可以使用.contentDocument(首选)来获取引用的svg,或者使用.getSVGDocument,这可能更兼容旧的svg插件。

这里有一个示例,展示了如何获取引用的svg的DOM。


示例链接是否已损坏? - Goswin Rothenthal
@Goswin 奇怪,看起来是网页服务器故障,文件确实存在...希望它很快就能正常工作。 - Erik Dahlström
3
请注意,.contentDocument 可以访问由<object><iframe>元素引用的外部 SVG 文件,但无法访问由 <embed> 元素引用的文件,而 .getSVGDocument() 可以从这三个元素中访问相同的文件。然而,.getSVGDocument() 已被弃用,因此仅在实际需要处理 <embed> 元素时才应使用。还要注意,.contentDocument 是一个(非函数)属性,而 .getSVGDocument() 是一个方法(因此需要括号)。 - Andrew Willems
1
任何需要使用<img/>标签的人(例如,如果您无法控制SVG资源),可能想了解有关附加SVG片段标识符的信息,例如"<img src="myimage.svg#svgView(preserveAspectRatio(none))" />",它允许您像使用内联SVG定义一样控制纵横比、viewBox等。 - brichins
document.querySelector('#id-of-object-containing-svg').contentDocument.querySelector('svg').outerHTML - A2D

17
我很确定这是不可能的。外部SVG与内联SVG不同,它不是DOM的一部分,我认为您无法从加载文档中访问SVG DOM树。
您可以使用AJAX请求将SVG作为XML加载,并将其插入DOM作为内联SVG,然后可以遍历和操作它。这个D3示例演示了这种技术。我认为这里使用的d3.xml()函数与jQuery的$.ajax()dataType: "xml"大致相当。

7
你可以使用<object><embed><iframe>标签来加载SVG文件,这些标签都允许你获取DOM。 - Erik Dahlström
真的吗?我正在尝试一下,但是jQuery和element.childNodes似乎都没有显示任何暴露的SVG DOM。你有例子吗? - nrabinowitz
1
示例:http://xn--dahlstrm-t4a.net/svg/html/get-embedded-svg-document-script.html。请提供翻译后的文本。 - Erik Dahlström
3
谢谢,这很棒 - 我从未听说过“getSVGDocument”。你应该将其提交为答案 - 我认为这是一个比我的更简单、直接的方法。 - nrabinowitz
nrabinowitz: 同意,Erik Dahlstrom在这里提供的示例是一个很好的解决方案 - 你通过代理获得赏金点数! - A2D
这个问题有一个非常流行的答案,介绍如何将一个SVG格式的img转换为SVG内联格式。https://dev59.com/S2ct5IYBdhLWcg3wmOZN - Simon_Weaver

2
不可能,但是你可以将<img>转换为<svg>,如此处所述(下面提供了相同的代码),并且你可以在DOM中访问svg的节点。
<script type="text/javascript">

    $(document).ready(function() {
        $('#img').each(function(){
            var img         = $(this);
            var image_uri   = img.attr('src');

            $.get(image_uri, function(data) {
                var svg = $(data).find('svg');
                svg.removeAttr('xmlns:a');
                img.replaceWith(svg);
            }, 'xml');

        });
    });
</script>


<img id='img' src="my.svg" />

1
如果您正在使用SVG内联到CSS中的url(data:...)或仅使用url(*.svg)背景,您可以使用svg-embed将它们嵌入到DOM中。
支持Chrome 11+,Safari 5+,FireFox 4+和IE9+。

0
如果您正在使用可以获取文件并插入的后端语言,那么至少可以改善作者的体验。例如:
<?php echo file_get_contents("kiwi.svg"); ?>

这里有一个与PHP相关的小事情...有人向我展示了file_get_contents()是正确的函数,而不是我之前使用的include()或include_once()。具体原因是SVG有时会被导出为带有作为开头行,这将导致PHP解析器无法处理它。
(信息摘自CSS-tricks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接