如何操作导入的 SVG 文件中的内部元素

How to manipulate internal elements from an imported SVG file

我正在使用 SVG.js 库来操作一个现有的 SVG 文件。我用 Inkscape 创建了这张图片:http://svgur.com/i/100.svg

我想做的是访问内部粉红色矩形并为其设置动画,但我什至不知道如何 select 该特定元素。

我有一个简单的 'test.html':<div id="drawing"></div>

然后我可以使用以下行成功加载图像:

var draw = SVG('drawing').size(500, 500);
var use  = draw.use('svg8', BASE_URL + '/app/test/test.svg');
use.move(0, 0);

现在如何访问 SVG 文件的内部元素 <rect id="rect4928"></rect>

非常感谢。

您可以将 id 添加到该元素并使用:

var element = SVG.get('purple_rect');
element.move(30,30);

这是来自文档,您可以轻松操作元素。这是codepen示例 http://codepen.io/anon/pen/peKzYM#anon-login

经过这几天的学习,我意识到我想做的事情是不可能的。当您通过 <use> 属性导入一个特定的 SVG 图像时,该图像将作为单个元素导入,所有内部元素都进入阴影 DOM 并且它们不再可访问。您可以在这篇文章中阅读 CSS 的非常好的解释和可能的解决方法:https://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/

在我的例子中,即使 <use> 元素已将所有内部元素放入常规 DOM 中,这也是不够的。我需要完全相同的图像在同一个 HTML 中出现 8 次,我还需要单独修改每个 SVG 图像的所有内部元素(上面的示例只是一个简化版本,在真实场景中我有一个包含大约 15 个我必须转换的内部元素的图像:更改颜色、旋转...)。出于这个原因,我必须为每个内部元素分配一个唯一的 ID,例如,如果我有一个包含 15 个内部元素并重复 8 次的 SVG,最后我需要 125 个唯一的 ID。

我最后做的是在 Inkscape 中创建这 8 张图像中的一张。之后,我构建了一个简单的 Java 程序来制作原始文件的 8 个副本,并为将在最终 HTML 中共存的所有元素提供唯一 ID。一旦我有了 8 个具有唯一 ID 的相同 SVG 副本,我就将它们中的每一个直接嵌入到 HTML 中,现在我可以使用 vanilla JS 轻松访问所有内容(我真的不再需要 SVG.js )

接下来您可以看到我尝试执行的操作的最终结果:https://jsfiddle.net/6shzx7Lk/

在最终图片中,我有 8 个蓝色 SVG 文件、8 个黄色块和 2 个灰色块。例如,您可以看到每个蓝色图像内部都有 10 个绿色点,如果您检查源代码,您可以看到每个点都有一个唯一的 ID。这样我就可以轻松地修改所有 8 个蓝色图像中的每个绿点(以及内部的其余元素)。我还可以通过根据用户屏幕大小排列不同的元素,使用 Bootstrap 调整最终图像的大小。

我不知道是否有更好的方法来实现这一点,但在最近几天使用 SVG 后,这是我为我的特定问题找到的解决方案。

非常感谢您的帮助。

如果你只是使用 vanilla JS,你可以这样做。您不必创建唯一的 ID。

用对象标签嵌入你的 svgs

<object id="svg1" data="100.svg" type="image/svg+xml"></object>
<object id="svg2" data="100.svg" type="image/svg+xml"></object>

然后使用这个javascript。

window.onload = function (){
    var c = document.getElementById("svg1").contentDocument;
    var rect = c.getElementById("rect4928");
    rect.setAttribute("style", "fill: green;");

    var c2 = document.getElementById("svg2").contentDocument;
    var rect = c2.getElementById("rect4928");
    rect.setAttribute("style", "fill: green;");
}