LitElement SVG子级作为插槽

时间:2019-02-18 17:20:21

标签: javascript svg web-component lit-element

我正在尝试将Lit-Element与SVG元素包裹的单个插槽一起使用。

但是似乎<slot>中的<svg>不接受渲染给定的SVG元素。

在自定义组件中无效的内容:

render() {
  return html`
  <svg>
    <slot><circle id="defaultCircle" cx=... cy=...></circle></slot>
  </svg>`
}

这里是一个示例:https://stackblitz.com/edit/wy6bhj?file=index.html

知道为什么吗?还有其他选择吗?

2019-02-18评论

Justin Fagnani建议使用<foreignObject>来混合HTML(即广告位)和SVG。不幸的是,这不起作用,因为在插槽中仍然是SVG元素。

2019-02-19更新

我使用render()函数内部表达的JavaScript,试图使用this.children来迭代子模板并将其添加到模板中。现在,使用检查器,它可以正确显示在DOM中,但是SVG元素不会呈现任何内容。我迷路了,不明白为什么不渲染圆。

https://stackblitz.com/edit/wy6bhj-hne7wl?file=my-element.js

2019-02-19 UPADTE2

我终于明白,我不可能像最初想要的那样去做。 我选择按原样传递SVG容器。

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

然后<my-element>使用

const SVG_CONTAINER = this.children[0]
const NODES = SVG_CONTAINERS.children

计算事物。瞧!

2 个答案:

答案 0 :(得分:1)

我认为您不能在SVG中使用 import java.util.*; public class Main { public static void main (String[] args) { // normalizeText(); // obify( "THISISSOMEREALLYGREATTEXT" ); // caesarify( "", 3 ); //text = ask the user for the test //size = as the user for the size of each chunk groupify( "", 0, "" ); } // Part 1 Normalized Method to convert all letter to uppercase and enter code hereremoving all special characters and placing it into String codey. public static String normalizeText ( ) { Scanner sc = new Scanner( System.in ); String normText; System.out.println( "Please input text to encrypt" ); normText = sc.nextLine(); System.out.println( normText.replaceAll( " ", "" ).replaceAll( "[^a-zA-Z ]", "" ).toUpperCase() ); return normText; } //This method will take in the Normalized text and insert a capital O and B in-front of every vowel and return the text private static String obify (String input) { String obifiledInput = ""; char c; for (int i = 0; i < input.length(); i++) { c = input.charAt( i ); if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'Y') { obifiledInput += "OB"; } obifiledInput += c; } System.out.println( obifiledInput ); return obifiledInput; } // Part 3 Method Caesarify that shifts each individual character by certain number key*// private static String caesarify (String c, int shift) { Scanner sc = new Scanner( System.in ); String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; String result = ""; System.out.println( "Enter the text you wish to encrypt" ); c = sc.nextLine(); System.out.println( "Enter a number how many places you wish to shift your text up and down the alphabet" ); shift = sc.nextInt(); for (int counter = 0; counter < c.length(); counter++) { char v = c.charAt( counter ); int i = alphabet.indexOf( v ); int f = i + shift; if (f >= 0) { if (f > 25) { while (f > 25) { f -= 26; } } } else { while (f < 0) { f += 26; } } result = result + alphabet.charAt( f ); } return result; } // This method should break a String up into parts whose length is determined by the integer. // The last parse should be padded with 'x' to fill the segment length. public static String groupify (String theTest, int lengthOfEachChunck, String text) { Scanner sc = new Scanner( System.in ); String result = ""; System.out.println( "Input text you wish to separate into groups" ); theTest = sc.nextLine(); System.out.println( "How many groups do you wish to break this up into?" ); lengthOfEachChunck = sc.nextInt(); StringBuffer sbSpace = new StringBuffer(); for (int i = 0; i <= lengthOfEachChunck; i++) { sbSpace.append( " "); } char[] letter = theTest.toCharArray(); for (int i = 0; i < letter.length; i++) {`enter code here` String str = String.valueOf( sbSpace ); result = str + letter[i]; System.out.print( result); } return result; }

简化代码以查看其作用。

以下是本机自定义元素,允许您嵌入内部内容。内部内容是SVG。我将值添加到SVG中以使其正常工作。

<slot>
class MyElement extends HTMLElement {
  constructor() {
    super();
    const s = this.attachShadow({mode:'open'});
    s.innerHTML = `<div>Your SVG</div>
      <div style="border:1px solid blue;width:20px;height:20px;"><slot></slot></div>`;
  }
}
customElements.define('my-element', MyElement);

现在让我们尝试使用svg而不是div来做到这一点:

<my-element>
<svg height="20" width="20">
<circle cx=10 cy=10 r=10 fill=red></circle>
</svg>
</my-element>
class MyElement extends HTMLElement {
  constructor() {
    super();
    const s = this.attachShadow({mode:'open'});
    s.innerHTML = `<div>Your SVG</div>
      <svg height="20" width="20" style="border:1px solid blue;"><slot></slot></svg>`
  }
}
customElements.define('my-element', MyElement);

如果深入研究开发工具,您将看到SVG拒绝接受插槽标记作为子代。我认为SVG不支持<my-element> <circle cx=10 cy=10 r=10 fill=red></circle> </my-element>,但我不确定。我只是不认为您可以按照自己的方式去做。

答案 1 :(得分:1)

svg 要求渲染时间。这是您问题的替代方案。您可以通过使用生命周期来解决。但理想情况下,您需要采取另一种方法。每个 svg 都应该竞争,svg 可以有多个 svg。例如,您可以将 svg 作为图标。一盏 svgs 是一个图标集,它是您的组件。

Attached image