Polymer.js是否支持内部SVG元素?

时间:2014-03-14 00:19:52

标签: svg polymer

我看到在自定义元素(例如here)中使用SVG元素的示例,但到目前为止,我还没有弄清楚如何定义自定义元素以进入 一个SVG元素。

我尝试过以下操作,虽然模板内容确实出现在网络检查器中,但圆圈并没有直观显示。

<polymer-element name=my-element noscript>
  <template>
    <circle cx=10 cy=10 r=5 />
  </template>
</polymer-element>

<svg>
    <my-element />
</svg>

是否有一个技巧让自定义元素在SVG元素中工作?

3 个答案:

答案 0 :(得分:16)

不幸的是,你不能这样做。 SVG名称空间中的元素必须在<svg>之内。创建<my-element>会创建一个继承自HTMLElement

的自定义元素

但是,您可以在自定义元素中添加<svg>http://jsbin.com/EXOWUFu/2/edit

另外,不要忘记自定义元素不能自动关闭。因此,在您的示例中,<my-element /> - &gt; <my-element></<my-element>。这是因为HTML规范只允许一些元素自动关闭。

<强>更新

事实证明,您可以使用<svg><foreignObject>内嵌入自定义元素。

演示:http://jsbin.com/hareyowi/1/edit

<foreignObject width="100" height="100">
  <x-foo></x-foo>
</foreignObject>

答案 1 :(得分:9)

Polymer FAQ显示模板可以在<svg>元素中使用:

<svg>
    <template repeat="{{l in lights}}">
        <circle cx="100" cy="{{l.cy}}" r="50" fill="{{l.color}}"/>
    </template>
</svg>

https://www.polymer-project.org/0.5/resources/faq.html#templateinsvg

确实这适用于Polymer 0.5! 但它在Polymer 0.9或1.0中工作。

在更改的Polymer 1.0语法中,它看起来像这样:

<svg>
    <template is="dom-repeat" items="{{lights}}">
        <circle cx="100" cy$="{{item.cy}}" r="50" fill$="{{item.color}}"/>
    </template>
</svg>

未呈现元素,浏览器控制台显示:

TypeError: node is undefined   in polymer.html:28

错误是指Polymer _parseNodeAnnotations()函数。

FAQ示例在0.5中工作显然表明SVG原则上不应该在Web Components或Polymer中工作。这让我希望Polymer团队能尽快解决这个问题。

答案 2 :(得分:1)

根据这个打开的票证(https://github.com/Polymer/polymer/issues/1976),你实际上可以在svg元素中嵌套一个模板元素。我将链接到下面的修复程序是0.5的代码端口。此处和打开的票证中详细描述了该问题,因此无需再次检查。

重要:

如果您想向Google和聚合物团队表明这确实是一项重要功能,请务必在机票上留言。

  • 它确实在聚合物1.0中提供了预期的功能。
  • 需要将其包含在可能使用它的每个Web组件的.js文件的顶部。
  • 它还假设一个特定的html结构(您将在下面看到)。
  • 它现在只适用于chrome。

代码段:https://gist.github.com/bendavis78/15528ca2f501c44f2fa4

<强> FOO-svg.css

foo-svg svg {
    border: 2px solid yellowgreen;
    fill: transparent;
    height: 400px;
    width: 400px;
}

<强> FOO-svg.html     

<dom-module id="foo-svg">
<link rel="stylesheet" href="foo-svg.css"/>

<template>
    <svg class="clock" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <template is="dom-repeat" items="{{positions}}" as="cx">
            <circle cx$="{{cx}}" cy="25" r="25" stroke="black" />
        </template>
    </svg>
</template>
<script src="foo-svg.js"></script>

<强> FOO-svg.js

(function () {
  // START HACK
  var doc = document.currentScript.ownerDocument;
  var root = doc.querySelector('dom-module > template').content;
  var templates = root.querySelectorAll('svg template');
  var el, template, attribs, attrib, count, child, content;
  for (var i=0; i<templates.length; i++) {
    el = templates[i];
    template = el.ownerDocument.createElement('template');
    el.parentNode.insertBefore(template, el);
    attribs = el.attributes;
    count = attribs.length;
    while (count-- > 0) {
      attrib = attribs[count];
      template.setAttribute(attrib.name, attrib.value);
      el.removeAttribute(attrib.name);
    }
    el.parentNode.removeChild(el);
    content = template.content;
    while ((child = el.firstChild)) {
      content.appendChild(child);
    }
  }
  // END HACK

  Polymer({
    is: 'foo-svg',

    properties: {
      paths: {
        type: Array,
        value: []
      }
    },

    ready () {
      this.positions = [0, 100, 200, 300];
    }
  });
})();