能否从包含SVG对象的HTML中导航SVG元素?

6
我正在通过object标签加载SVG,并需要访问SVG的元素(以操纵它们)。我该怎么做?
以下是我知道的部分解决方案:
1. 使用SVG参数,在object标记中设置参数并将SVG元素的属性参数化。这对像rect这样的东西非常有效,但不适用于我需要移动的g(组)(需要一个无法参数化的“transform”)。
2. 我看到有人建议在getElementById(“yoursvgid”)中使用contentDocument或getSVGDocument()获取对象元素。不幸的是,两者都不起作用 - 是的,我在SVG加载后调用这些函数。
我无法相信没有一种简单/可靠的方法从HTML内部访问SVG元素(在此处/网络上搜索)-真的很感谢您的帮助!
或者,如果有一种方法可以从HTML中调用在SVG内定义的函数(或反之亦然),那也可以。总的来说,任何在SVG和HTML之间通信的方式。

2
嗯...如果不想使用对象标签,你可以使用内联SVG。 - yankee
你知道吗?你可以在XHTML中嵌入SVG - Phrogz
是的,但我也想要兼容IE8(不幸的是我不能忽略它...至少现在还不能)。或者IE8也有内联解决方案吗? - Sekhar
4个回答

2

我尝试了这里或其他地方建议的不同组合/解决方案,看起来处理SVG的最佳方法是将SVG元素嵌入HTML中 - 只需确保将其命名为.xhtml。一旦你这样做了,就可以简单地导航DOM并做想做的事情(就像yankee建议的那样)。

我已经验证了这在当前版本的Chrome、FF、Safari、IE和Opera中有效。它也适用于IE8。下面是一个粗略的示例,其中包含一个按钮和一个渐变条 - 如果你点击按钮,它会将条变成红色。

<button style="display: block;" onclick="document.getElementById('color').setAttribute('style', 'stop-color:#FF0000');">Color</button>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="49px" height="376px" viewBox="0 0 49 376" enable-background="new 0 0 49 376" xml:space="preserve">
<g>
    <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="24" y1="376" x2="24" y2="1.0005">
        <stop  offset="0" style="stop-color:#FFFFFF"/>
        <stop id="color" offset="1" style="stop-color:#000000"/>
    </linearGradient>
    <path fill="url(#SVGID_1_)" d="M48,366c0,5.522-4.477,10-10,10H10c-5.523,0-10-4.478-10-10V11C0,5.477,4.477,1,10,1h28
        c5.523,0,10,4.477,10,10V366z"/>
</g>
</svg>

2

这里有一个我成功使用过的技巧,出自(非常好的)O'Reilly《SVG Essentials》书中:

  1. Add JavaScript code to your SVG document itself and handle the load event on the root svg element.

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
    <script type="text/ecmascript" xlink:href="svgScript.js" />
    
  2. In this svgScript.js load event handler, write out whatever you need to expose to the HTML-side script through the built-in parent variable.

    function init(evt) {
        svgDocument = evt.target.ownerDocument;
        parent.theSvgDocument = svgDocument;
    }
    
  3. Back in your HTML-side script, you can now directly access and use this reference.

    var svgDocument = theSvgDocument;
    
在这个例子中,我们暴露了SVG文档对象,但是你也可以传递任何对象或函数。在我的项目中,我实际上暴露了某种控制器对象引用,以便我的SVG脚本包含操作SVG文档的所有逻辑,而HTML脚本仅仅抓取这个控制器对象并调用它的公共方法。

谢谢,是的,我也尝试过在SVG中使用parent,但是值没有传递到HTML中(变量未定义)。同样,在Chrome(v9)上出现了这个问题;例如,在FF3.6上它可以正常工作。 - Sekhar

0
如果你的第二个选项不起作用,我想看看你的示例。你在测试哪些浏览器?你是否使用了SVG插件?
选项2)是Acid3测试检查的内容之一(子测试#74)。

不确定Acid3测试的问题。在Chrome 9中,我的代码中的contentDocument和getSVGDocument()都返回未定义,但Acid3测试给出了100/100的结果。我已经在其他浏览器上进行了测试,FF3.6 / IE9 / Opera11都返回对象 - 所以问题只存在于Chrome中(没有特别检查IE8)。 - Sekhar

0

你能使用SVGweb吗?这里有一个使用'object'标签的示例。虽然我不是SVGweb专家,但我在Chrome检查器中看到

不过,这是另一个依赖项(而且它们还依赖于IE的条件注释,不确定在你的情况下是否可接受)。

或者,你可以从他们的源代码中学习,看看他们是如何做到的。(天啊,他们在那里放了大量的文档!)


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